Webview in recyclerview - webview

I have a list of webview to show different pdf's, I need to show it in a horizontal RecyclerView, but the problem is that when I scroll it horizontally then the coming webview just goes on top of the current one and the current one instead of shifting to the left hand side, it remains at its position. It looks a little weird.
This is my RecyclerViewAdapter
public class HorizontalManual extends RecyclerView
.Adapter {
Context context;
private ArrayList<String> list;
public class DataObjectHolder extends RecyclerView.ViewHolder {
ImageView imgUploaded;ProgressBar loader; WebView webViewManual;
public DataObjectHolder(View itemView) {
super(itemView);
webViewManual = (WebView) itemView.findViewById(R.id.pdf_manual_webView);
}
}
public HorizontalManual(Context context, ArrayList<String> list) {
this.context = context;
this.list = list;
}
#Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = null;
try {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.horz_pdf, parent, false);
if (view.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT)
view.getLayoutParams ().width = parent.getWidth ();
} catch (Exception e) {
e.printStackTrace();
}
return new DataObjectHolder(view);
}
#Override
public void onBindViewHolder(final DataObjectHolder holder, final int position) {
String url = "http://docs.google.com/gview?embedded=true&url=" + list.get(position);
Log.e("pdf",url);
WebSettings websettings = holder.webViewManual.getSettings();
websettings.setJavaScriptEnabled(true);
holder.webViewManual.loadUrl(url);
holder.webViewManual.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
holder.webViewManual.loadUrl("javascript:(function() { " +
"document.getElementsByClassName('ndfHFb-c4YZDc-GSQQnc-LgbsSe ndfHFb-c4YZDc-to915-LgbsSe VIpgJd-TzA9Ye-eEGnhe ndfHFb-c4YZDc-LgbsSe')[0].style.display='none'; })()");
}
});
holder.webViewManual.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
holder.webViewManual.setHorizontalScrollBarEnabled(false);
}
#Override
public int getItemCount() {
return list.size();
}
}
I'm setting the HorizontalList in my Fragment like this:
mRecyclerViewManual.setHasFixedSize(true);
rLayoutManagerManual = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false); mRecyclerViewManual.setLayoutManager(rLayoutManagerManual);
//Setting adapter
HorizontalManual setUploadsListAdapterManual = new HorizontalManual(context, list); mRecyclerViewManual.setAdapter(setUploadsListAdapterManual);

Load you google doc url using iframe tag as shown below.
String frameVideo = "<html><body>Youtube video .. <br> <iframe width=\"320\" height=\"315\" src=\"https://docs.google.com/gview?embedded=true&url=http://Dealerapp.ebunch.ca/upload/wl/manuals/7.pdf\" frameborder=\"0\" allowfullscreen></iframe></body></html>";
holder.webView.loadData(frameVideo, "text/html", "utf-8");

Related

Can't update Item from RecycleView using a Custom Adapter and Listener

I have an updateTask method which opens an alert dialog. I am trying to call this method through a listener in the onBindViewHolder function in my custom adapter.
However my alert dialog does not pop up and while debugging I found out that my update task method is not called.
Please help me understand why.
Thanks
Here is my customAdapter:
public class TasksAdapter extends RecyclerView.Adapter<TasksAdapter.TaskViewHolder> {
private ArrayList<Model> tasks;
private TaskUpdateListener listener;
TasksAdapter(ArrayList<Model> tasks,TaskUpdateListener listener) {
this.tasks = tasks;
this.listener = listener;
}
#Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.retrieved_layout, parent, false);
return new TaskViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull TaskViewHolder holder, int position) {
Model task = tasks.get(position);
holder.setDate(task.getDate());
holder.setTask(task.getTask());
holder.setDesc(task.getDescription());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String taskString = task.getTask();
String descString = task.getDescription();
listener.onTaskUpdate(task, position);
}
});
}
#Override
public int getItemCount() {
return tasks.size();
}
public static class TaskViewHolder extends RecyclerView.ViewHolder {
View mView;
public TaskViewHolder(#NonNull View itemView) {
super(itemView);
mView = itemView;
}
public void setTask(String task) {
TextView taskTextView = mView.findViewById(R.id.taskTv);
taskTextView.setText(task);
}
public void setDesc(String desc) {
TextView descTextView = mView.findViewById(R.id.descriptionTv);
descTextView.setText(desc);
}
public void setDate(String date) {
TextView dateTextView = mView.findViewById(R.id.dateTv);
}
}
public interface TaskUpdateListener {
void onTaskUpdate(Model model, int position);
}
}
And here is my HomeActivity:
public class HomeActivity extends AppCompatActivity {
private Toolbar toolbar;
private RecyclerView recyclerView;
private FloatingActionButton floatingActionButton;
private FirebaseDatabase database = FirebaseDatabase.getInstance();
private DatabaseReference userTasksRef;
private FirebaseAuth mAuth;
private FirebaseUser mUser;
private String onlineUserID;
private ProgressDialog loader;
private String key = "";
private String task;
private String description;
#Override
public void onBackPressed(){
new AlertDialog.Builder(this)
.setMessage("Are you sure you want exit ?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("No", null)
.show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_home);
toolbar = findViewById(R.id.homeToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Todo List App");
mAuth = FirebaseAuth.getInstance();
recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
loader = new ProgressDialog(this);
mUser = mAuth.getCurrentUser();
onlineUserID = mUser.getUid();
database = FirebaseDatabase.getInstance("https://todolist-bbccd-default-rtdb.europe-west1.firebasedatabase.app");
userTasksRef = database.getReference("users").child(onlineUserID).child("tasks");
floatingActionButton = findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addTask();
}
});
}
private void addTask() {
AlertDialog.Builder myDialog = new AlertDialog.Builder(this);
LayoutInflater inflater = LayoutInflater.from(this);
View myView = inflater.inflate(R.layout.input_file, null);
myDialog.setView(myView);
final AlertDialog dialog = myDialog.create();
dialog.setCancelable(false);
final EditText task = myView.findViewById(R.id.task);
final EditText description = myView.findViewById(R.id.description);
Button save = myView.findViewById(R.id.saveBtn);
Button cancel = myView.findViewById(R.id.CancelBtn);
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String mTask = task.getText().toString().trim();
String mDescription = description.getText().toString().trim();
String id = userTasksRef.push().getKey();
String date = DateFormat.getDateInstance().format(new Date());
if (TextUtils.isEmpty(mTask)) {
task.setError("Task Required");
return;
}
if (TextUtils.isEmpty(mDescription)) {
description.setError("Description Required");
return;
} else {
loader.setMessage("Adding your data");
loader.setCanceledOnTouchOutside(false);
loader.show();
Model model = new Model(mTask, mDescription, id, date);
userTasksRef.child(id).setValue(model).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(HomeActivity.this, "Task has been inserted successfully", Toast.LENGTH_SHORT).show();
loader.dismiss();
} else {
String error = task.getException().toString();
Toast.makeText(HomeActivity.this, "Failed: " + error, Toast.LENGTH_SHORT).show();
loader.dismiss();
}
}
});
}
dialog.dismiss();
}
});
dialog.show();
}
#Override
protected void onStart() {
super.onStart();
ArrayList<Model> tasks = new ArrayList<>();
userTasksRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot taskSnapshot : dataSnapshot.getChildren()) {
Model task = taskSnapshot.getValue(Model.class);
tasks.add(task);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
// Handle errors here
}
});
TasksAdapter.TaskUpdateListener listener = new TasksAdapter.TaskUpdateListener() {
#Override
public void onTaskUpdate(Model model, int position) {
updateTask(model, position);
}
};
TasksAdapter adapter = new TasksAdapter(tasks, listener);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
public void updateTask(Model task, final int position ) {
AlertDialog.Builder myDialog = new AlertDialog.Builder(this);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.update_data, null);
myDialog.setView(view);
final AlertDialog dialog = myDialog.create();
final EditText mTask = view.findViewById(R.id.mEditTextTask);
final EditText mDescription = view.findViewById(R.id.mEditTextDescription);
mTask.setText(task.getTask());
mTask.setSelection(task.getTask().length());
mDescription.setText(task.getDescription());
mDescription.setSelection(task.getDescription().length());
Button delButton = view.findViewById(R.id.btnDelete);
Button updateButton = view.findViewById(R.id.btnUpdate);
updateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String tasktxt = mTask.getText().toString().trim();
String descriptiontxt = mDescription.getText().toString().trim();
String date = DateFormat.getDateInstance().format(new Date());
Model model = new Model(tasktxt, descriptiontxt, key, date);
userTasksRef.child(key).setValue(model).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(HomeActivity.this, "Data has been updated successfully", Toast.LENGTH_SHORT).show();
}else {
String err = task.getException().toString();
Toast.makeText(HomeActivity.this, "update failed "+err, Toast.LENGTH_SHORT).show();
}
}
});
dialog.dismiss();
}
});
}
}

how do I highlight the searched text using android search view Widget?

My search view is working properly but I am trying to do a search such that all the "visible" search letters should be highlighted. I used the filter interface in my adapter for filtering data.
here is my adapter Class
public class myAdapter extends RecyclerView.Adapter<myAdapter.viewHolder> implements Filterable {
private List<Model> model;
// for search filtering
private ArrayList<Model> modelFull;
Context context;
public myAdapter(ArrayList<Model> model, Context context) {
this.model = model;
modelFull =new ArrayList<>(model);
this.context = context;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.template, parent, false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
Model forPosition = model.get(position);
holder.image.setImageResource(forPosition.getImage());
holder.intro.setText(forPosition.getIntro());
}
#Override
public int getItemCount() {
return model.size();
}
public class viewHolder extends RecyclerView.ViewHolder {
TextView intro;
ImageView image;
public viewHolder(#NonNull View itemView) {
super(itemView);
intro= itemView.findViewById(R.id.introTxt);
image = itemView.findViewById(R.id.image);
}
}
#Override
public Filter getFilter() {
return generalFilter;
}
private Filter generalFilter =new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Model> filteredModel =new ArrayList<>();
if(constraint ==null || constraint.length()==0) {
filteredModel.addAll(modelFull);
}
else {
String searchQuery= constraint.toString().toLowerCase().trim();
for(blogBigModel item : modelFull){
if(item.getBlogIntro().toLowerCase().contains(searchQuery)){
filteredModel.add(item);
}
}
}
FilterResults results =new FilterResults();
results.values = filteredModel;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
model.clear();
model.addAll((List)results.values);
notifyDataSetChanged();
}
};
}
that's my class / Fragment where i used the above adapter
[what should i add to get the desired highlighted query when i search in the search bar like Whatsapp][1]
[1]: https://i.stack.imgur.com/Fdu2r.jpg
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_home_search:enter code here
SearchView searchView = (SearchView) item.getActionView();
searchView.setQueryHint("Search....");
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setBackground(getResources().getDrawable(R.drawable.searchview_bg));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
}
}
return true;
});

viewholder onclickListener null object reference

Attempt to invoke interface method 'void com.example.imovie.adapter.MovieItemClickListener.onMovieClick(com.example.imovie.models.Movie, android.widget.ImageView)' on a null object reference
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MyViewHolder> {
Context context ;
List<Movie> mData;
MovieItemClickListener movieItemClickListener;
public MovieAdapter(Context context, List<Movie> mData, MovieItemClickListener listener) {
this.context = context;
this.mData = mData;
movieItemClickListener = listener;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.item_movie,viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.TvTitle.setText(mData.get(i).getTitle());
myViewHolder.ImgMovie.setImageResource(mData.get(i).getThumbnail());
}
#Override
public int getItemCount() {
return mData.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView TvTitle;
private ImageView ImgMovie;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
TvTitle = itemView.findViewById(R.id.item_movie_title);
ImgMovie = itemView.findViewById(R.id.item_movie_img);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
movieItemClickListener.onMovieClick(mData.get(getAdapterPosition()),ImgMovie);//i have a null object reference
}
});
}
}
}
public class HomeFragment extends Fragment implements MovieItemClickListener {
private HomeViewModel homeViewModel;
private List<Slide> listSlides;
private ViewPager slidePager;
private TabLayout indicator;
private RecyclerView moviesRV;
private RecyclerView moviesRV2;
private MovieItemClickListener movieItemClickListener;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
slidePager = root.findViewById(R.id.slider_pager);
indicator = root.findViewById(R.id.indicator);
moviesRV = root.findViewById(R.id.rsViewMovies);
moviesRV2 = root.findViewById(R.id.rsViewMovies2);
iniSlider();
final SliderPagerAdapter sliderPagerAdapteradapter = new SliderPagerAdapter(getContext(), listSlides);
final MovieAdapter movieAdapter = new MovieAdapter(getContext(), DateSource.getPopularMovies(), movieItemClickListener);
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new SliderTimer(), 4000, 6000);
homeViewModel.getText().observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
slidePager.setAdapter(sliderPagerAdapteradapter);
indicator.setupWithViewPager(slidePager, true);
moviesRV.setAdapter(movieAdapter);
moviesRV.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
moviesRV2.setAdapter(movieAdapter);
moviesRV2.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
}
});
return root;
}
#Override
public void onMovieClick(Movie movie, ImageView imageView) {
Intent intent = new Intent(getContext(), MovieDetailActivity.class);
intent.putExtra("title", movie.getTitle());
intent.putExtra("imgURL", movie.getThumbnail());
intent.putExtra("imgCover", movie.getCoverPhoto());
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(getActivity(),
imageView, "sharedName");
startActivity(intent, options.toBundle());
Toast.makeText(getContext(), "item clicked : " + movie.getTitle(), Toast.LENGTH_LONG).show();
}
class SliderTimer extends TimerTask {
#Override
public void run() {
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (slidePager.getCurrentItem() < listSlides.size() - 1) {
slidePager.setCurrentItem(slidePager.getCurrentItem() + 1);
} else {
slidePager.setCurrentItem(0);
}
}
});
}
}
}
private void iniSlider() {
listSlides = new ArrayList<>();
listSlides.add(new Slide(R.drawable.a, "slide title \n movie title"));
listSlides.add(new Slide(R.drawable.b, "slide title"));
listSlides.add(new Slide(R.drawable.a, "slide title \n movie title"));
listSlides.add(new Slide(R.drawable.b, "slide title"));
}
}
If I'm not wrong, HomeFragment.movieItemClickListener is never initialized.
You may want to make the following changes in HomeFragment:
1. Delete the line
private MovieItemClickListener movieItemClickListener;
2. In this line
final MovieAdapter movieAdapter = new MovieAdapter(getContext(), DateSource.getPopularMovies(), movieItemClickListener);
change movieItemClickListener to this, because HomeFragment implements MovieItemClickListener.
That should fix the NullPointerException.

Checkbox enable EditText in RecyclerView issue

I am working for quiz app project. I've got a RecyclerView, each of them contains TextView, two Checkbox and EditText. What I want is when i checked the second Checkbox it will enable the EditText. I have already make this work. but the problem is if I Checked the Checkbox and Type something in the EditText on the first row, when I scroll down some of the others are mirroring the EditText state even I am not Checked the Checkbox to enable EditText of that row.
here is my adapter code:
public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.StudentViewHolder> {
private LayoutInflater inflator;
private int status;
Typeface typeface;
List<Student> students = Collections.emptyList();
public StudentAdapter(Context context, List<Student> students, String Font) {
inflator = LayoutInflater.from(context);
this.students = students;
typeface = Typeface.createFromAsset(context.getAssets(), Font);
}
#Override
public StudentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflator.inflate(R.layout.student_row, parent, false);
StudentViewHolder studentViewHolder = new StudentViewHolder(view);
return studentViewHolder;
}
#Override
public void onBindViewHolder(final StudentViewHolder holder, final int position) {
final Student currentStudent = students.get(position);
holder.studentName.setText(currentStudent.student);
holder.chbIllegal.setTag(students.get(position));
holder.editText.setTag(students.get(position));
holder.chbIllegal.setChecked(students.get(position).isSelected());
holder.chbIllegal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
final Student contact = (Student) cb.getTag();
contact.setSelected(cb.isChecked());
students.get(position).setSelected(cb.isChecked());
// this will enable editText if checkbox is checked
if (cb.isChecked()) {
holder.editText.setEnabled(true);
holder.editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String Illegal = holder.editText.getText().toString();
contact.setAgaints_rule(Illegal);
Log.d("GExam", currentStudent.student + " " + Illegal);
}
});
holder.chbIllegal.setOnClickListener(null);
holder.chbIllegal.setTag(students.get(position));
} else {
holder.editText.setEnabled(false);
}
}
});
if (currentStudent.getStatus() == 1) {
holder.chbPresent.setChecked(true);
} else if (currentStudent.getStatus() == 0) {
holder.chbPresent.setChecked(false);
}
}
#Override
public int getItemCount() {
return students.size();
}
class StudentViewHolder extends RecyclerView.ViewHolder {
TextView studentName;
CheckBox chbPresent, chbIllegal;
EditText editText;
public StudentViewHolder(View itemView) {
super(itemView);
studentName = (TextView) itemView.findViewById(R.id.StudentlistText);
this.studentName.setTypeface(typeface);
editText = (EditText) itemView.findViewById(R.id.edtAgaintsRule);
chbPresent = (CheckBox) itemView.findViewById(R.id.chbPresent);
// chbIllegal will handle the editText
chbIllegal = (CheckBox) itemView.findViewById(R.id.chbIllegal);
editText.setEnabled(false);
}
}
public List<Student> getStudentList() {
return students;
}
}
How can I only enable EditText of the row that checkbox is checked?
Finally I've been able to solve my problem by my teacher helped. what I have changed is I move the listener from onBindViewHolder to my ViewHolder class like this:
public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.StudentViewHolder> {
private LayoutInflater inflator;
private int status;
Typeface typeface;
List<Student> students = Collections.emptyList();
public StudentAdapter(Context context, List<Student> students, String Font) {
inflator = LayoutInflater.from(context);
this.students = students;
typeface = Typeface.createFromAsset(context.getAssets(), Font);
}
#Override
public StudentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflator.inflate(R.layout.student_row, parent, false);
StudentViewHolder studentViewHolder = new StudentViewHolder(view);
return studentViewHolder;
}
#Override
public void onBindViewHolder(final StudentViewHolder holder, final int position) {
final Student currentStudent = students.get(position);
holder.studentName.setText(currentStudent.student);
holder.chbIllegal.setTag(students.get(position));
holder.editText.setTag(students.get(position));
holder.editText.setText(currentStudent.getAgaints_rule());
if (currentStudent.isSelected()) {
holder.editText.setEnabled(true);
}else{
holder.editText.setEnabled(false);
}
holder.chbIllegal.setChecked(students.get(position).isSelected());
if (currentStudent.getStatus() == 1) {
holder.chbPresent.setChecked(true);
} else if (currentStudent.getStatus() == 0) {
holder.chbPresent.setChecked(false);
}
}
#Override
public int getItemCount() {
return students.size();
}
class StudentViewHolder extends RecyclerView.ViewHolder {
TextView studentName;
CheckBox chbPresent, chbIllegal;
EditText editText;
public StudentViewHolder(View itemView) {
super(itemView);
studentName = (TextView) itemView.findViewById(R.id.StudentlistText);
this.studentName.setTypeface(typeface);
editText = (EditText) itemView.findViewById(R.id.edtAgaintsRule);
chbPresent = (CheckBox) itemView.findViewById(R.id.chbPresent);
chbIllegal = (CheckBox) itemView.findViewById(R.id.chbIllegal);
chbIllegal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Student s = (Student) v.getTag();
Log.e("GExam", String.valueOf(cb.isChecked()));
s.setSelected(cb.isChecked());
StudentViewHolder.this.editText.setEnabled(cb.isChecked());
}
});
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
Student student = (Student) StudentViewHolder.this.editText.getTag();
student.setAgaints_rule(s.toString());
}
});
}
}
public List<Student> getStudentList() {
return students;
}
}

Can only parse TITLE tag -- LINK, DESCRIPTION, PUBDATE and others will not parse. (RSS / SAX)

I'm new to android development and I have been struggling to parse more than one tag at a time and display it in a ListView.
I'm using SAX parser, here is my RssParseHandler code.
public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
private RssItem currentMessage;
//private StringBuilder builder;
private boolean parseLink;
private boolean parseTitle;
private boolean parseDate;
private boolean parseDes;
public RssParseHandler() {
rssItems = new ArrayList();
}
public List<RssItem> getItems() {
return this.rssItems;
}
#Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.equalsIgnoreCase("item")) {
this.currentMessage = new RssItem();
} else if (localName.equalsIgnoreCase("title")) {
//currentMessage.setTitle(builder.toString());
parseTitle = true;
} else if (localName.equalsIgnoreCase("link")) {
//currentMessage.setLink(builder.toString());
parseLink = true;
} else if (localName.equalsIgnoreCase("description")) {
//currentMessage.setDescription(builder.toString());
parseDes = true;
} else if (localName.equalsIgnoreCase("pubDate")) {
//currentMessage.setDate(builder.toString());
parseDate = true;
}
//parsing enclosure tag
else if ("enclosure".equals(localName)) {
// Get tags attributes number
int attrsLength = attributes.getLength();
for (int i = 0; i < attrsLength; i++) {
String attrName = attributes.getQName(i); // attribute name
if ("url".equals(attrName)) // This tag has only one attribute but it is better to check it name is correct
currentMessage.getLink();
}
}
}
#Override
public void endElement(String uri, String localName, String name)
throws SAXException {
super.endElement(uri, localName, name);
if (this.currentMessage != null) {
if (localName.equalsIgnoreCase("item")) {
rssItems.add(currentMessage);
//currentMessage = null;
} else if (localName.equalsIgnoreCase("link")) {
//currentMessage.setLink(builder.toString());
//parseLink = false;
} else if (localName.equalsIgnoreCase("description")) {
//currentMessage.setDescription(builder.toString());
//parseDes = false;
} else if (localName.equalsIgnoreCase("pubDate")){
//currentMessage.setDate(builder.toString());
parseDate = false;
} else if (localName.equalsIgnoreCase("title")) {
//currentMessage.setTitle(builder.toString());
parseTitle = false;
}
//builder.setLength(0);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
//builder.append(ch, start, length);
if (parseTitle) {
if (currentMessage != null)
currentMessage.setTitle(new String(ch, start, length));
} else if (parseLink) {
if (currentMessage != null) {
currentMessage.setLink(new String(ch, start, length));
//parseLink = false;
}
} else if (parseDes) {
if (currentMessage != null)
currentMessage.setDescription(new String(ch, start, length));
//parseLink = false;
} else if (parseDate) {
if (currentMessage != null) {
currentMessage.setDate(new String(ch, start, length));
//currentMessage.setDate(new String(ch, start, length));
//parseDesc = false;
}
}
}
}
Here is the code for the Listview:
public class ReaderAppActivity extends Fragment {
private ReaderAppActivity local;
private ListView mList;
/**
* This method creates main application view
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//super.onCreate(savedInstanceState);
// Set view
//setContentView(R.layout.fragment_rss);
local = this;
//int position = getArguments().getInt("position");
// String url = getArguments().getString("url");
// List of rivers
String[] menus = getResources().getStringArray(R.array.menus);
// Creating view corresponding to the fragment
View v = inflater.inflate(R.layout.fragment_rss, container, false);
// Set reference to this activity
//local = this;
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://thechurchofwhatshappeningnow.libsyn.com/rss");
//task.execute(url);
// Debug the thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
//mList = (ListView) findViewById(R.id.rssListMainView);
return v;
}
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
#Override
protected List<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("ITCRssReader", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(List<RssItem> result) {
// Get a ListView from main view
ListView mList = (ListView) getView().findViewById(R.id.rssListMainView);
// Create a list adapter
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.rss_text, result);
//ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.fragment_rss, result);
// Set list adapter for the ListView
mList.setAdapter(adapter);
// Set list view item click listener
mList.setOnItemClickListener(new ListListener(result, getActivity()));
}
}
}
What am I doing wrong? I can't figure it out. I would like to parse, the link, description, pubDate, and pass them into the ListView. Ideally I would only display the title and episode number in the listview, and pass the other tags into String, so I can display them when I click an item in the listView.
I've created another class called SingleMenuItem to be called when I click an item in the ListView, it's just filler code right now, it does not display anything because the items aren't parsed.
Any help would be appreciated. Here is a RSS link to the feed:
public class SingleMenuItem extends Activity {
// XML node keys
static final String KEY_NAME = "name";
static final String KEY_DATE = "pubdate";
static final String KEY_DESC = "description";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_list_item);
// getting intent data
Intent in = getIntent();
// Get XML values from previous intent
String name = in.getStringExtra(KEY_NAME);
String date = in.getStringExtra(KEY_DATE);
String description = in.getStringExtra(KEY_DESC);
// Displaying all values on the screen
TextView lblName = (TextView) findViewById(R.id.name_label);
TextView lblDate = (TextView) findViewById(R.id.date_label);
TextView lblDesc = (TextView) findViewById(R.id.description_label);
lblName.setText(name);
lblDate.setText(date);
lblDesc.setText(description);
}
}
Here is the code for my ReaderAppActivty that puts the results of the parsing into the ListView:
public class ReaderAppActivity extends Fragment {
private ReaderAppActivity local;
private ListView mList;
/**
* This method creates main application view
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//super.onCreate(savedInstanceState);
// Set view
//setContentView(R.layout.fragment_rss);
local = this;
//int position = getArguments().getInt("position");
// String url = getArguments().getString("url");
// List of rivers
String[] menus = getResources().getStringArray(R.array.menus);
// Creating view corresponding to the fragment
View v = inflater.inflate(R.layout.fragment_rss, container, false);
// Set reference to this activity
//local = this;
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://thechurchofwhatshappeningnow.libsyn.com/rss");
//task.execute(url);
// Debug the thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
//mList = (ListView) findViewById(R.id.rssListMainView);
return v;
}
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
#Override
protected List<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("ITCRssReader", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(List<RssItem> result) {
// Get a ListView from main view
ListView mList = (ListView) getView().findViewById(R.id.rssListMainView);
// Create a list adapter
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.rss_text, result);
//ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.fragment_rss, result);
// Set list adapter for the ListView
mList.setAdapter(adapter);
// Set list view item click listener
mList.setOnItemClickListener(new ListListener(result, getActivity()));
}
}
}
Based on the amount of commented-out code in your RssParseHandler, you've clearly been struggling with this for a bit, and some early attempts were closer to right than what you've got now.
The issue with your current code appears to be that you're not consistently resetting the booleans that drive which part of the item you're setting. Debugging through it, I saw it setting a date into the link field at some point.
But you're actually doing some of that setting in the wrong method, as the characters method doesn't necessarily give you the full contents of the tag. You need to use a Stringbuilder, and I can see from commented-out code that you tried that at some point.
If you collect the text in a stringbuilder and do all the setting in the endElement method, you don't really need the booleans at all, as the endElement method has knowledge of which tag you're ending.
Here's a working version that's perhaps not too far from something you had at some point but which gets rid of all those flag fields.
public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
private RssItem currentMessage;
private StringBuilder builder;
public RssParseHandler() {
rssItems = new ArrayList<>();
builder = new StringBuilder();
}
public List<RssItem> getItems() {
return this.rssItems;
}
#Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
builder.setLength(0);
if (localName.equalsIgnoreCase("item")) {
this.currentMessage = new RssItem();
}
}
#Override
public void endElement(String uri, String localName, String name)
throws SAXException {
super.endElement(uri, localName, name);
if (this.currentMessage != null) {
if (localName.equalsIgnoreCase("item")) {
rssItems.add(currentMessage);
currentMessage = null;
} else if (localName.equalsIgnoreCase("link")) {
currentMessage.setLink(builder.toString());
} else if (localName.equalsIgnoreCase("description")) {
currentMessage.setDescription(builder.toString());
} else if (localName.equalsIgnoreCase("pubDate")){
currentMessage.setDate(builder.toString());
} else if (localName.equalsIgnoreCase("title")) {
currentMessage.setTitle(builder.toString());
}
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
builder.append(ch, start, length);
}
}

Resources