Show the latest item firest in Firebase ui Realtime database [duplicate] - java

I try to use the FirebaseUI-Realtime Database Android lib to simply display a data set in a viepager2 with recycler-view adapter
When I get the data, I got the oldest data first, and i need to show the latest first . So I need a reverse order. How i can do it in RecyclerView adapter?
MainActivity.java
public class MainActivity extends AppCompatActivity {
ViewPager2 viewPager2;
videoadapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
viewPager2 = (ViewPager2) findViewById(R.id.vpager);
FirebaseRecyclerOptions<videomodel> options = new FirebaseRecyclerOptions.Builder<videomodel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("videos"), videomodel.class).build();
adapter = new videoadapter(options);
viewPager2.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
}
videoadapter.java
public class videoadapter extends
FirebaseRecyclerAdapter<videomodel, videoadapter.myviewholder> {
private Context context;
private AppCompatActivity activity;
private Timer _timer = new Timer();
private double positionc;
private TimerTask check;
private ProgressBar progressbar11;
private ViewPager2 viewPager;
public videoadapter(#NonNull FirebaseRecyclerOptions<videomodel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myviewholder holder, int position, #NonNull videomodel model) {
holder.setdata(model);
holder.simpleExoPlayer.prepare();
}
#NonNull
#Override
public myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_video_row, parent, false);
return new myviewholder(view);
}
#Override
public void onViewAttachedToWindow(videoadapter.myviewholder holder) {
super.onViewAttachedToWindow(holder);
holder.playerView.getPlayer().seekTo(0);
holder.playerView.getPlayer().setPlayWhenReady(true);
holder.playerView.getPlayer().prepare();
}
#Override
public void onViewDetachedFromWindow(videoadapter.myviewholder holder) {
super.onViewDetachedFromWindow(holder);
holder.playerView.getPlayer().setPlayWhenReady(false);
holder.playerView.getPlayer().stop();
}
class myviewholder extends RecyclerView.ViewHolder {
PlayerView playerView;
SimpleExoPlayer simpleExoPlayer;
LinearLayout sec_mid;
ProgressBar progressbar1;
DefaultTrackSelector trackSelector;
ImageView play,pause;
TextView title,desc;
public myviewholder(#NonNull View view) {
super(view);
playerView = (PlayerView) view.findViewById(R.id.statusSliderVideo);
sec_mid = (LinearLayout) view.findViewById(R.id.sec_controlvid1);
progressbar1 = (ProgressBar) view.findViewById(R.id.progressbar11);
play = (ImageView) view.findViewById(R.id.exo_play);
pause = (ImageView) view.findViewById(R.id.exo_pause);
title = (TextView) view.findViewById(R.id.textVideoTitle);
desc = (TextView) view.findViewById(R.id.textVideoDescription);
}
void setdata(videomodel obj) {
progressbar1.getProgressDrawable().setColorFilter(Color.WHITE, android.graphics.PorterDuff.Mode.SRC_IN);
progressbar1.setIndeterminate(true);
title.setText(obj.getTitle());
desc.setText(obj.getDesc());
// get data
Uri videoUri = Uri.parse(obj.getUrl());
simpleExoPlayer = new SimpleExoPlayer.Builder(playerView.getContext()).build();
playerView.setPlayer(simpleExoPlayer);
playerView.setKeepScreenOn(true);
MediaItem mediaItem = MediaItem.fromUri(videoUri);
simpleExoPlayer.setMediaItem(mediaItem);
simpleExoPlayer.prepare();
playerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View _view) {
if (simpleExoPlayer.isPlaying()) {
simpleExoPlayer.pause();
} else {
simpleExoPlayer.play();
}
}
});
simpleExoPlayer.addListener(new Player.Listener() {
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == Player.STATE_BUFFERING) {
progressbar1.setIndeterminate(true);
} else {
progressbar1.setIndeterminate(false);
}
if (playbackState == Player.STATE_ENDED) {
simpleExoPlayer.seekTo(0);
simpleExoPlayer.setPlayWhenReady(true);
}
}
});
Activity activity = new Activity();
check = new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
progressbar1.setMax((int) simpleExoPlayer.getDuration());
progressbar1.setProgress((int) simpleExoPlayer.getCurrentPosition());
}
});
}
};
_timer.scheduleAtFixedRate(check, (int) (0), (int) (1));
}
}
}
videomodel
public class videomodel {
String desc,title,url;
public videomodel(String desc, String title, String url) {
this.desc = desc;
this.title = title;
this.url = url;
}
videomodel()
{
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

Related

How to open new activity in recyclerview with firebase database

Im creating a recipe app in android studios with categories(chicken,pork,beef etc) and subcategories. But I still can't figure out how to open new activity for my sub categories when i click the categories without passing the same data. BTW im using recyclerview and firebase for my database. Hope someone can help! Thanks
MainActivity.class
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
MainAdapter mainAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.recView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerOptions<MainModel> options =
new FirebaseRecyclerOptions.Builder<MainModel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("category"), MainModel.class)
.build();
mainAdapter = new MainAdapter(options);
recyclerView.setAdapter(mainAdapter);
}
#Override
protected void onStart() {
super.onStart();
mainAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
mainAdapter.stopListening();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search,menu);
MenuItem item = menu.findItem(R.id.search);
SearchView searchView = (SearchView)item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
txtSearch(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
txtSearch(query);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
private void txtSearch(String str)
{
FirebaseRecyclerOptions<MainModel> options =
new FirebaseRecyclerOptions.Builder<MainModel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("category").orderByChild("name").startAt(str).endAt(str+"~"), MainModel.class)
.build();
mainAdapter = new MainAdapter(options);
mainAdapter.startListening();
recyclerView.setAdapter(mainAdapter);
}
}
MainAdapter.class
public class MainAdapter extends FirebaseRecyclerAdapter<MainModel,MainAdapter.myViewHolder> {
/**
* Initialize a {#link RecyclerView.Adapter} that listens to a Firebase query. See
* {#link FirebaseRecyclerOptions} for configuration options.
*
* #param options
*/
public MainAdapter(#NonNull FirebaseRecyclerOptions<MainModel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull MainAdapter.myViewHolder holder, int position, #NonNull MainModel model) {
holder.categoryName.setText(model.getName());
holder.categoryDesc.setText(model.getDescription());
Glide.with(holder.categoryImage.getContext())
.load(model.getImage())
.placeholder(R.drawable.common_google_signin_btn_icon_dark)
.error(R.drawable.common_google_signin_btn_icon_dark_normal)
.into(holder.categoryImage);
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_item,parent,false);
return new myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder{
ImageView categoryImage;
TextView categoryName, categoryDesc;
public myViewHolder(#NonNull View itemView) {
super(itemView);
categoryImage = (ImageView)itemView.findViewById(R.id.categoryImage);
categoryName = (TextView)itemView.findViewById(R.id.categoryName);
categoryDesc = (TextView)itemView.findViewById(R.id.categoryDesc);
}
}
}
MainModel.class
public class MainModel {
String name,description,image;
MainModel()
{
}
public MainModel(String name, String description, String image) {
this.name = name;
this.description = description;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
Add this in your OnBindviewHolder method of Adapter
context = holder.itemView.getContext();
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, YourActivity.class);
context.startActivity(i);
}
});

How to pause ExoPlayer playerView when RecyclerView.SCROLL_STATE_DRAGGING and release player on Destroy

I want to implement a RecyclerView that works similar to Instagram feeds, that contains both Image and Video Items. I have successful implemented the recyclerView to display both image and video items, but I am having issues with pausing the video items when the onScrollListener is on RecyclerView.SCROLL_STATE_DRAGGING I am using ExoPlayer library for the video player"
So, if a video is played and the recyclerView is not pause it keeps on playing that video even if another video is played from the list. Making multiple video playing at the same time.
Below is my implementation Adapter
public class RecyclerAdapter extends RecyclerView.Adapter {
private ArrayList<ListModel> listModelList;
private Context context;
SimpleExoPlayer exoPlayer;
public RecyclerAdapter(ArrayList<ListModel> listModelList, Context context) {
this.listModelList = listModelList;
this.context = context;
}
#Override
public int getItemViewType(int position) {
if (listModelList.get(position).getDescription().equalsIgnoreCase("video")) {
return 1;
} else {
return 0;
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view;
if (viewType == 0) {
view = inflater.inflate(R.layout.recycler_item, parent, false);
return new AdsViewHolder(view);
} else {
view = inflater.inflate(R.layout.video_item, parent, false);
return new VideoVH(view);
}
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, int position) {
ListModel listModel = listModelList.get(position);
if (listModel.getDescription().equalsIgnoreCase("video")) {
VideoVH videoVH = (VideoVH) holder;
initPlayer(((VideoVH) holder).playerView, listModel.getMedia_url(), ((VideoVH) holder).progressBar);
((VideoVH) holder).titleText.setText(listModel.getTitle());
((VideoVH) holder).descText.setText(listModel.getDescription());
//Play video
} else {
AdsViewHolder adsViewHolder = (AdsViewHolder) holder;
((AdsViewHolder) holder).titleText.setText(listModel.getTitle());
((AdsViewHolder) holder).descText.setText(listModel.getDescription());
Glide.with(context)
.load(listModel.getMedia_url())
.into(((AdsViewHolder) holder).imageView);
}
}
private void initPlayer(final PlayerView playerView, String uri, final ProgressBar progressBar) {
TrackSelector trackSelector = new DefaultTrackSelector();
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
playerView.setPlayer(exoPlayer);
exoPlayer.setPlayWhenReady(false);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "ExoRecyclerView"));
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(uri));
exoPlayer.prepare(videoSource);
playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
exoPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
exoPlayer.seekTo(500);
exoPlayer.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
// Log.e(TAG, "onPlayerStateChanged: Buffering video.");
if (progressBar != null) {
progressBar.setVisibility(VISIBLE);
}
break;
case Player.STATE_ENDED:
break;
case Player.STATE_IDLE:
break;
case Player.STATE_READY:
// Log.e(TAG, "onPlayerStateChanged: Ready to play.");
if (progressBar != null) {
progressBar.setVisibility(GONE);
}
break;
default:
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
#Override
public int getItemCount() {
return listModelList.size();
}
class AdsViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView titleText, descText;
public AdsViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.thumbnail);
descText = itemView.findViewById(R.id.desc);
titleText = itemView.findViewById(R.id.title);
}
}
class VideoVH extends RecyclerView.ViewHolder {
PlayerView playerView;
TextView titleText, descText;
ConstraintLayout VV;
ProgressBar progressBar;
ImageView volumeControl;
public VideoVH(#NonNull View itemView) {
super(itemView);
playerView = itemView.findViewById(R.id.playerView);
descText = itemView.findViewById(R.id.desc);
titleText = itemView.findViewById(R.id.title);
volumeControl = itemView.findViewById(R.id.volume_control);
VV = itemView.findViewById(R.id.parent);
progressBar = itemView.findViewById(R.id.progressBar);
}
}
}
MainActivity imoplementation
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
ArrayList<ListModel> listModelList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerView);
ListModel listModel = new ListModel();
listModelList.add(new ListModel("One test",
"https://res.cloudinary.com/dqrs5xew4/image/upload/v1591991924/sample.jpg", "image"));
listModelList.add(new ListModel("One test",
"https://res.cloudinary.com/dqrs5xew4/video/upload/v1595538345/HNG/b5bc3f170b7d5c388410bcca0a501ecd_lnhzwn.mp4", "video"));
listModelList.add(new ListModel("One test",
"https://res.cloudinary.com/dqrs5xew4/image/upload/v1591991924/sample.jpg", "image"));
listModelList.add(new ListModel("One test",
"https://res.cloudinary.com/dqrs5xew4/video/upload/v1595538331/HNG/VID-20180713-WA0009_esbmff.mp4", "video"));
listModelList.add(new ListModel("One test",
"https://res.cloudinary.com/dqrs5xew4/image/upload/v1591991924/sample.jpg", "image"));
initRecyclerView();
}
private void initRecyclerView() {
// use a linear layout manager
LinearLayoutManager layoutManager =
new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
RecyclerAdapter mAdapter = new RecyclerAdapter(listModelList, MainActivity.this);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
}
Model Class
public class ListModel {
private String title;
private String media_url;
private String description;
public ListModel(String title, String media_url, String description) {
this.title = title;
this.media_url = media_url;
this.description = description;
}
public ListModel() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMedia_url() {
return media_url;
}
public void setMedia_url(String media_url) {
this.media_url = media_url;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
I have gone through several question here and on youtube, But they all implemeted just a single view type in the recyclerView.
Any suggestion how I could control the Video Player when the recyclerView is been scrolled? Or a better way I could implement the Instagram feeds like RecyclerView

How to implement onClick in FirestoreRecyclerAdapter to open a new Fragment?

I am trying to implement OnClick in my recyclerview,but i failed miserably with all the searches how to solve this problem.
I want by clicking on my cardview to go to another activity/even better fragment with another expandable lists,but i can't even do this for now.
Any help is highly appreciated
MainActivity code
package com.oleg.firestoretest;
public static final String TAG = "FireLog";
private CollectionReference noteBookRef;
private FirebaseFirestore mFirestore;
private NoteAdapter adapter;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirestore = FirebaseFirestore.getInstance();
noteBookRef = mFirestore.collection("Notebook");
setupRecyclerView();
}
private void setupRecyclerView() {
Query query = noteBookRef.orderBy("priority", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Note> options = new FirestoreRecyclerOptions.Builder<Note>()
.setQuery(query,Note.class)
.build();
adapter = new NoteAdapter(options);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
public Note() {
}
public Note(String title, String content, int priority) {
this.title = title;
this.content = content;
this.priority = priority;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public int getPriority() {
return priority;
}
}
public class NoteAdapter extends FirestoreRecyclerAdapter<Note, NoteAdapter.NoteHolder> {
private Context mContext;
public NoteAdapter(#NonNull FirestoreRecyclerOptions<Note> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull NoteHolder noteHolder, int i, #NonNull Note note) {
noteHolder.title.setText(note.getTitle());
noteHolder.content.setText(note.getContent());
noteHolder.priority.setText(String.valueOf(note.getPriority()));
}
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.note_item,
parent, false);
return new NoteHolder(v);
}
class NoteHolder extends RecyclerView.ViewHolder {
TextView title;
TextView content;
TextView priority;
public NoteHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title_text);
content = itemView.findViewById(R.id.content_text);
priority = itemView.findViewById(R.id.priority_text);
}
}
}
Here the Code u need:
class NoteHolder extends RecyclerView.ViewHolder {
TextView title;
TextView content;
TextView priority;
CardView cardView;
public NoteHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title_text);
content = itemView.findViewById(R.id.content_text);
priority = itemView.findViewById(R.id.priority_text);
cardView = itemView.findViewById(R.id.cardView);
}
private void bind(){
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(FirstActivity.this, SecoundActivity.class);
startActivity(intent);
}
});
}
}
Fixed it with this code!!!
public NoteHolder(#NonNull final View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.cardview);
title = itemView.findViewById(R.id.title_text);
content = itemView.findViewById(R.id.content_text);
priority = itemView.findViewById(R.id.priority_text);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
itemView.getContext().startActivity(new Intent(itemView.getContext(),Empty.class));
}
});
}

RecyclerView doesn't inflate, rather updates the same view?

I have an activity to implement a to-do list, containing a recyclerview with each item being a checkbox and textview, and each task is added from an edittext.
It stores data using Realm.io. The behaviour that I keep getting is that the single element in the recyclerview merely get updated, and not inflated! Please help.
TasksActivity -
public class TasksActivity extends AppCompatActivity implements View.OnClickListener{
TextView courseTitle;
RecyclerView TaskList;
EditText addTask;
Button addButton;
String transName; //Transferred Course name from MainActivity
TaskAdapter TA;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks);
courseTitle = findViewById(R.id.CourseName);
TaskList = findViewById(R.id.TaskListRV);
TaskList.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
addTask = findViewById(R.id.InputTask);
addButton = findViewById(R.id.AddTaskButton);
//Course name is the obtained from the previous acivity.
transName =getIntent().getExtras().getString("CourseName");
courseTitle.setText(transName);
TA = new TaskAdapter(transName);
TaskList.setAdapter(TA);
addButton.setOnClickListener(this);
}
#Override
public void onClick(View view) {
String task = addTask.getText().toString();
// Checking if the text is empty.
boolean flag = false;
for(int i = 0;i<task.length();i++)
{
if(task.charAt(i)!=' ')
flag = true;
}
if(!flag || task.equals(""))
{
Toast emptyWarning = Toast.makeText(getApplicationContext(),"Task cannot be Empty!",Toast.LENGTH_SHORT);
emptyWarning.show();
}
else
{
addTask.setText("");
TA.addNewTask(task);
}
}
}
TasksAdapter -
public class TaskAdapter extends RecyclerView.Adapter<TaskViewHolder> implements RealmChangeListener<RealmResults<TaskModel>>
{
private ArrayList<TaskModel> TaskList;
private String course;
private final Realm realm;
public TaskAdapter(String course)
{
this.course = course;
this.TaskList = new ArrayList<>();
realm = Realm.getDefaultInstance();
loadTaskData();
}
void loadTaskData()
{
RealmResults<TaskModel> taskModelRealmResults = realm.where(TaskModel.class).equalTo("courseName",course).findAll();
taskModelRealmResults.addChangeListener(this);
for(TaskModel iTM : taskModelRealmResults)
{
TaskList.add(realm.copyFromRealm(iTM));
}
notifyDataSetChanged();
}
#Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view= layoutInflater.inflate(R.layout.item_task,parent,false);
TaskViewHolder Tvh = new TaskViewHolder(view);
return Tvh;
}
#Override
public void onBindViewHolder(TaskViewHolder holder, int position) {
holder.populateTask(TaskList.get(position));
}
#Override
public int getItemCount() {
return TaskList.size();
}
public void addNewTask(String task)
{
TaskModel newTaskObj = new TaskModel(task,course,false);
TaskList.add(newTaskObj);
notifyDataSetChanged();
realm.beginTransaction();
realm.insertOrUpdate(newTaskObj);
realm.commitTransaction();
}
#Override
public void onChange(RealmResults<TaskModel> taskModels) {
taskModels = realm.where(TaskModel.class).equalTo("courseName",course).findAll();
this.TaskList = new ArrayList<>();
for(TaskModel iTM : taskModels)
{
this.TaskList.add(realm.copyFromRealm(iTM));
}
notifyDataSetChanged();
}
}
TaskViewHolder and TaskModel - (in case you might need them)
public class TaskModel extends RealmObject {
String task;
#PrimaryKey
String courseName;
boolean isDone;
public TaskModel() {
task = "";
courseName = "";
isDone = false;
}
public TaskModel(String task, String courseName, boolean isDone) {
this.task = task;
this.courseName = courseName;
this.isDone = isDone;
}
public String getTask() {
return task;
}
public void setTask(String task) {
this.task = task;
}
public boolean isDone() {
return isDone;
}
public void setDone(boolean done) {
isDone = done;
}
}
public class TaskViewHolder extends RecyclerView.ViewHolder {
CheckBox isdone;
TextView Taskname;
public TaskViewHolder(View itemView) {
super(itemView);
isdone = itemView.findViewById(R.id.TaskCheckBox);
Taskname = itemView.findViewById(R.id.TaskName);
}
void populateTask(final TaskModel T)
{
Taskname.setText(T.getTask());
isdone.setChecked(T.isDone());
isdone.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
T.setDone(isdone.isChecked());
}
});
}
}
I advise you to use Realm Android dapter, this adapter is taking care of updating your app UI. Don't need to implement OnChangeListener, your list will be automatically updated after insertion, deletion or edition
Use findAllAsync in order to not block the UI thread
OrderedRealmCollection<TaskModel> taskModels = realm.where(TaskModel.class).equalTo("courseName", course).findAllAsync();
public RealmAdapter(OrderedRealmCollection<TaskModel> data) {
super(data, true);
}
EDIT:
Also always do the process using Async method when it's possible. You can replace your addNewTask method by:
public void addNewTask(String task) {
final TaskModel newTaskObj = new TaskModel(task, course, false);
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(newTaskObj);
}
});
}
Yous should have something like this:
TasksActivity
public class TasksActivity extends AppCompatActivity implements View.OnClickListener {
private EditText addTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks);
String transName = getIntent().getExtras().getString("CourseName");
TextView courseTitle = findViewById(R.id.CourseName);
courseTitle.setText(transName);
addTask = findViewById(R.id.InputTask);
findViewById(R.id.AddTaskButton).setOnClickListener(this);
OrderedRealmCollection<TaskModel> taskModels = Realm.getDefaultInstance().where(TaskModel.class).equalTo("courseName", transName).findAllAsync()
TaskAdapter adapter = new TaskAdapter(this, taskModels);
RecyclerView taskList = findViewById(R.id.TaskListRV);
taskList.setLayoutManager(new LinearLayoutManager(this));
taskList.setAdapter(adapter);
}
#Override
public void onClick(View view) {
String task = addTask.getText().toString().trim();
if (task.trim().isEmpty()) {
Toast emptyWarning = Toast.makeText(getApplicationContext(),"Task cannot be Empty!",Toast.LENGTH_SHORT);
emptyWarning.show();
return;
}
addTask.setText("");
addNewTask(task);
}
private void addNewTask(String task) {
final TaskModel newTaskObj = new TaskModel(task, course, false);
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(newTaskObj);
}
});
}
}
And TaskAdapter:
public class TaskAdapter extends RealmRecyclerViewAdapter<TaskModel, TaskViewHolder> {
private LayoutInflater layoutInflater
public TaskAdapter(Context context, OrderedRealmCollection<TaskModel> taskModels) {
super(taskModels, true);
this.layoutInflater = LayoutInflater.from(context);
}
#Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new TaskViewHolder(layoutInflater.inflate(R.layout.item_task , parent, false));
}
#Override
public void onBindViewHolder(TaskViewHolder holder, int position) {
holder.populateTask(getItem(position));
}
}
OP here. I ended up using the standard ReacyclerView.Adapter.
The problem was with the usage of Realm's insertOrUpdate method, when the #PrimaryKey was courseName which thus caused it to indeed update the same object and not create a new one!
insert() should have been used.
Here is the insert task method -
public void addNewTask(String task)
{
boolean flag = false;
for(int i = 0;i<TaskList.size();i++)
{
if(task.equals(TaskList.get(i).getTask()))
{
Toast.makeText(context,"Task already exists!",Toast.LENGTH_SHORT).show();
flag = true;
break;
}
}
if(!flag)
{
TaskModel newTaskObj = new TaskModel();
newTaskObj.setTask(task);
newTaskObj.setDone(false);
newTaskObj.setCourseName(course);
TaskList.add(newTaskObj);
notifyDataSetChanged();
realm.beginTransaction();
realm.insert(newTaskObj);
realm.commitTransaction();
} }
The entire project can be found here, do check it out -
https://github.com/Hariram-R/ToDoList-App

onClickListener in RecyclerView.ViewHolder

I've got a RecyclerView.ViewHolder and RecyclerView.Adapter, I need after click on item and then send information about this item to another Activity.
PlacesAdapter.java
public class PlacesAdapter extends RecyclerView.Adapter<PlacesViewHolder> {
private PlacesActivity placesActivity;
Context context;
private int position;
List<Places> places;
public PlacesAdapter(List<Places> places) {
this.places = places;}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PlacesViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.places_view, viewGroup, false);
PlacesViewHolder pvh = new PlacesViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PlacesViewHolder personViewHolder, int i) {
personViewHolder.name.setText(places.get(i).name);
personViewHolder.address.setText(places.get(i).address);
Picasso.with(personViewHolder.itemView.getContext())
.load(places.get(i).photo)
.into(personViewHolder.getPhoto());
}
#Override
public int getItemCount() {
return places.size();
}
}
PlacesViewHolder.java
In this line "intent.putExtra(PlacesDetail.PLACES_NAME,);" How can I send name?
public class PlacesViewHolder extends RecyclerView.ViewHolder {
CardView cv;
public TextView name;
public TextView address;
public ImageView photo;
public PlacesViewHolder(final View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
name = (TextView)itemView.findViewById(R.id.person_name);
address = (TextView)itemView.findViewById(R.id.person_age);
photo = (ImageView)itemView.findViewById(R.id.person_photo);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, PlacesDetail.class);
intent.putExtra(PlacesDetail.PLACES_NAME,);
context.startActivity(intent);
}
});
}
public TextView getAddress() {
return address;
}
public TextView getName() {
return name;
}
public ImageView getPhoto() {
return photo;
}
}
This is the complete example of custom Adapter where i'm able to get the details of particular items. In MainActivity you need to set the adapter :
adapter = new MyAdapter(getApplicationContext(), account_no, title, aFN1, aLN1,aFN2, aLN2,aFN3, aLN3,isavilable,waitlist,flag);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
Now see the code for the custom Adapter :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
String TAG = "MyAdapter";
Context context;
private String[] accountNo;
private String[] title;
private String[] afn1;
private String[] aln1;
private String[] afn2;
private String[] aln2;
private String[] afn3;
private String[] aln3;
private String[] isAvailable;
private String[] waitlist;
private int flag;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView account_no,title,afn1,afn2,aln1,aln2,color,is_available;
private ImageView img_android;
CardView cardView;
public ViewHolder(CardView v) {
super(v);
account_no = (TextView)v.findViewById(R.id.acctno);
title = (TextView)v.findViewById(R.id.title);
afn1 = (TextView) v.findViewById(R.id.afn1);
cardView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(Context context, String[] accountNo,String[] title,String[] afn1,String[] aln1,String[] afn2,String[] aln2,String[] afn3,String[] aln3,String[] isAvailable, String[] waitlist,int flag) {
this.context = context;
this.accountNo = accountNo;
this.title = title;
this.afn1 = afn1;
this.aln1 = aln1;
this.afn2 = afn2;
this.aln2 = aln2;
this.afn3 = afn3;
this.aln3 = aln3;
this.isAvailable = isAvailable;
this.waitlist = waitlist;
this.flag = flag;
Log.d(TAG,afn1.toString() +aln1+afn2+aln2+afn3+aln3.toString()+waitlist);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
CardView cv = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(cv);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final CardView cardView = holder.cardView;
final TextView accountno = (TextView)cardView.findViewById(R.id.acctno);
accountno.setText(accountNo[position]);
final TextView titletxt = (TextView)cardView.findViewById(R.id.title);
titletxt.setText(title[position]);
final TextView afn1txt = (TextView) cardView.findViewById(R.id.afn1);
afn1txt.setText(afn1[position]+" "+aln1[position]);
Log.d(TAG,waitlist[position]);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = getItemViewType(position);
SharedPreferences sharedPreferences = context.getSharedPreferences(Constant.MYPREFERENCE,Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString(Constant.ACCOUNT,accountNo[position]);
edit.putString(Constant.TITLE,title[position]);
edit.putString(Constant.AFN1,afn1[position]);
edit.putString(Constant.ALN1,aln1[position]);
edit.putString(Constant.AFN2,afn2[position]);
edit.putString(Constant.ALN2,aln2[position]);
edit.putString(Constant.AFN3,afn3[position]);
edit.putString(Constant.ALN3,aln3[position]);
edit.putBoolean(Constant.IS_AVAILABLE, Boolean.parseBoolean(isAvailable[position].toUpperCase()));
edit.putString(Constant.WAITLIST,waitlist[position]);
Log.d("WaitingNo2 :",""+String.valueOf(waitlist[position]));
edit.commit();
Intent intent = new Intent(v.getContext(), DetailsActivity.class);
v.getContext().startActivity(intent);
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return accountNo.length;
}
}
After All that get the value from sharedPreferences in the Activity which is called on Card Click:
preferences = getSharedPreferences("myshared", Context.MODE_PRIVATE);
AccountNo = sharedPreferences.getString(Constant.ACCOUNT,null).toUpperCase();
title = sharedPreferences.getString(Constant.TITLE,null).toUpperCase();
afn1 = sharedPreferences.getString(Constant.AFN1,null).toUpperCase();
aln1 = sharedPreferences.getString(Constant.ALN1,null).toUpperCase();
afn2 = sharedPreferences.getString(Constant.AFN2,null).toUpperCase();
aln2 = sharedPreferences.getString(Constant.ALN2,null).toUpperCase();
afn3 = sharedPreferences.getString(Constant.AFN3,null).toUpperCase();
aln3 = sharedPreferences.getString(Constant.ALN3,null).toUpperCase();
isAvailable = sharedPreferences.getBoolean(Constant.IS_AVAILABLE,isAvailable);
waitlist = sharedPreferences.getString(Constant.WAITLIST,waitlist);
Now do whatever you want and enjoy the code.
You can achieve this by creating an interface inside your adapter for an itemclicklistener and then you can set onItemClickListener from your PlacesActivity.
Somewhere inside your PlacesAdapter you would need the following:
private onRecyclerViewItemClickListener mItemClickListener;
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position, String places_name);
}
Then inside your ViewHolder (which I've added as an inner class inside my adapter), you would apply the listener to the components you'd like the user to click, like so:
class PlacesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
PlacesViewHolder(View view) {
super(view);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClickListener(v, getAdapterPosition(), PlacesDetail.PLACES_NAME);
}
}
}
This example shows an onClickListener being applied to the view inside PlacesViewHolder.
recyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.notifyDataSetChanged();// Notify the adapter
adapter.setOnItemClickListener(new PlacesAdapter.onRecyclerViewItemClickListener() {
#Override
public void onItemClickListener(View view, int position, String places_name) {
//perform click logic here (places_name is passed)
}
});
To implement this code, you would setOnItemClickListener to your adapter inside PlacesActivity as shown above.
try this , it's work with me correctly
Create a new class and this code
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
#Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
#Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
And in your Activity add this to your adapter implementation
mRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), mRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// do something
}
}
}
#Override
public void onLongItemClick(View view, int position) {
// do whatever
}
})
);

Categories