I have a RecyclerView filled with elements of the "Event" class. The class has parameters such as Date and Importance.
Now all Events in RecyclerView are displayed just like that.
I want to show Events by Date separately and also want to show Events by importance separately. I'll attach a picture to show what I mean.
I read that to do separation, for example, by dates, you need to make a separate adapter and viewholder. Question - if I want to split the same data array by importance, do I need to create another adapter?
And let's say I want to choose a grouping method. How can I do this and where?
My First RecyclerViewAdapter of Event
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
private static final String TAG = "myLogs";
private List<Event> mEventList;
final SparseBooleanArray selectedItems = new SparseBooleanArray();
private int currentSelectedPos;
public List<Event> getEvents(){
return mEventList;
}
private EventAdapterListener itemClickListener;
public interface EventAdapterListener {
void onItemClick(int position);
void onItemLongClick(int position);
}
public void setListener(EventAdapterListener listener){
itemClickListener = listener;
}
private OnItemCheckedListener OnItemChecked;
public interface OnItemCheckedListener {
void onItemChecked(int position, boolean isImportant);
}
public void setOnItemCheckedListener (OnItemCheckedListener listener){
OnItemChecked = listener;
}
public static class EventViewHolder extends RecyclerView.ViewHolder{
public TextView TVtitle;
public TextView TVcomment;
public CheckBox CBimportance;
public TextView TVdate;
//public EventViewHolder(#NonNull View itemView, final EventAdapterListener listener) {
public EventViewHolder(#NonNull View itemView) {
super(itemView);
TVtitle = itemView.findViewById(R.id.tvTitle);
TVcomment = itemView.findViewById(R.id.tvComment);
CBimportance = itemView.findViewById(R.id.cbIconImportant);
TVdate = itemView.findViewById(R.id.tvDate);
}
}
public void removeItem(int position) {
mEventList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mEventList.size());
}
private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){
#Override
public String[] getMonths() {
return new String[]{"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"};
}
};
public EventAdapter(ArrayList<Event> listEvent){
mEventList = listEvent;
}
#NonNull
#Override
public EventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_cardview, parent, false);
//LayoutInflater inflater = LayoutInflater.from(parent.getContext());
//if (viewType == Constants.VIEWTYPE_GROUP){
//ViewGroup group = (ViewGroup) inflater.inflate(R.layout.group_layout, parent, false);
//GroupViewHolder
//}
return new EventViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull EventViewHolder holder, final int position) {
final Event item = mEventList.get(position);
holder.TVtitle.setText(item.getName());
holder.TVcomment.setText(item.getComment());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM", myDateFormatSymbols);
holder.TVdate.setText(simpleDateFormat.format(item.getDate()));
holder.CBimportance.setOnCheckedChangeListener(null);
holder.CBimportance.setChecked(item.getImportant());
holder.CBimportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.IsImportant = b;
OnItemChecked.onItemChecked(position, b);
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (selectedItems.size() > 0 && itemClickListener != null){
itemClickListener.onItemClick(position);
}
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (itemClickListener != null){
itemClickListener.onItemLongClick(position);
}
return true;
}
});
if (currentSelectedPos == position) currentSelectedPos = -1;
}
#Override
public int getItemCount() {
return mEventList.size();
}
void deleteEvents(){
List<Event> events = new ArrayList<>();
for (Event event : mEventList){
if (event.getSelected())
events.add(event);
}
mEventList.removeAll(events);
notifyDataSetChanged();
currentSelectedPos = -1;
}
void toggleSelection(int position) {
currentSelectedPos = position;
if (selectedItems.get(position)) {
selectedItems.delete(position);
mEventList.get(position).setSelected(false);
} else {
selectedItems.put(position, true);
mEventList.get(position).setSelected(true);
}
notifyItemChanged(position);
}}
I would like to change the color when I click the Button in RecyclerView.
I want to change the text color of the 4 button when I click the button corresponding to position 4 of position 1, 2, 3, 4.
public class SingleAdapter extends RecyclerView.Adapter<SingleAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(int position);
void onLongItemClick(int position);
}
Context context;
List<SingleItem> items;
public static OnItemClickListener onItemClickListener;
public SingleAdapter(Context context, List<SingleItem> items) {
this.context = context;
this.items = items;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.onItemClickListener = onItemClickListener;
}
#Override
public int getItemCount() {
return items.size();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.single_item, parent, false);
final ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
SingleItem item = items.get(position);
viewHolder.btnItemButton.setText(item.getmSubText());
}
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
Button btnItemButton;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
btnItemButton = itemView.findViewById(R.id.itemButton);
btnItemButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(onItemClickListener != null)
{
onItemClickListener.onItemClick(getAdapterPosition());
}
}
#Override
public boolean onLongClick(View v) {
return false;
}
}
}
public class SingleItem {
String mSubText;
public SingleItem(String mSubText)
{
this.mSubText = mSubText;
}
public String getmSubText() {
return mSubText;
}
public void setmSubText(String mSubText)
{
this.mSubText = mSubText;
}
}
static String mAddListDepthUnits[] = { "m", "ft", "fm", "HR", "pb" };
private void setDepthRecycler()
{
singleItems = new ArrayList<>();
for( int i = 0; i < mAddListDepthUnits.length; i++)
{
singleItems.add(new SingleItem(mAddListDepthUnits[i]));
}
mSingleAdapter = new fec.fishfinderapp.menu.SingleAdapter(mSubMenu_Units.getContext(), singleItems);
midDepthRecycler.setAdapter(mSingleAdapter);
mSingleAdapter.setOnItemClickListener(new SingleAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
switch(position)
{
case 0 :
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
break;
}
}
#Override
public void onLongItemClick(int position) {
}
});
}
The current code is in this state.
How can I change the text color of a specific button here?
I can hardly find the answer.
Please help me
As my understanding you need to change the text color based on button click?
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
SingleItem item = items.get(position);
viewHolder.btnItemButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(position == 4) {
viewHolder.btnItemButton.setTextColor(Color.RED);
}else{
viewHolder.btnItemButton.setTextColor(Color.GREEN);
}
}
});
viewHolder.btnItemButton.setText(item.getmSubText());
}
I have to add Pagination in recyclerView. But I am stuck in adding a progressbar when recyclerView scroll.
I have been trying for a day but unfortunately not got a valid solution to add a progress bar at run time while recyclerView scrolling.I have three ViewHolder.
RecyclerView Scroll Listener
rvRewardItems.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = recyclerView.getChildCount();
int totalItemCount = wrapperLinearLayout.getItemCount();
int firstVisibleItem = wrapperLinearLayout.findFirstVisibleItemPosition();
int lastInScreen = firstVisibleItem + visibleItemCount;
if ((lastInScreen == totalItemCount) && !isLoadingMore) {
if (!mStopLoadingData) {
try {
isLoadingMore = true;
// Add item for progress ba
new Handler().post(new Runnable() {
#Override
public void run() {
adapter.addProgressView();
}
});
loadReviews(false, false);
}catch (IllegalStateException e){
e.printStackTrace();
}
}
}
}
});
RewardFinalAdapter.class
public class RewardFinalAdapter extends RecyclerView.Adapter<MainViewHolder>
{
private Context context;
private ArrayList<RewardItemBO> rewardArray;
private OnItemClickListener mItemClickListener;
public static final int VIEW_TYPE_PROGRESS = 0;
public static final int VIEW_TYPE_ITEM = 1;
public static final int VIEW_TYPE_HEADER = 2;
public RewardFinalAdapter(Context context, ArrayList<RewardItemBO> mainItems) {
this.context = context;
rewardArray = getFilterRewards(mainItems);
}
public void resetArray(ArrayList<RewardItemBO> latestArray)
{
rewardArray = getFilterRewards(latestArray);
}
public void setArrayItems(ArrayList<RewardItemBO> latestArray) {
rewardArray = latestArray;
}
#Override
public int getItemViewType(int position) {
if(rewardArray.get(position).isHeader())
return VIEW_TYPE_HEADER;
else if(rewardArray.get(position).isShowProgress())
return VIEW_TYPE_PROGRESS;
else
return VIEW_TYPE_ITEM;
}
#Override
public int getItemCount() {
return rewardArray.size();
}
public RewardItemBO getItem(int position) {
return rewardArray.get(position);
}
public void addItems( ArrayList<RewardItemBO> overallItem){
rewardArray = getFilterRewards(overallItem);
// notifyItemInserted(items.size() - 1);
this.notifyDataSetChanged();
}
// Create new views (invoked by the layout manager)
#Override
public MainViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType){
case VIEW_TYPE_HEADER:
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.order_list_header, viewGroup, false);
return new RewardListViewHolderHeader(itemView);
case VIEW_TYPE_ITEM:
View view = LayoutInflater.from(context).inflate(R.layout.item_rewards, viewGroup, false);
return new RewardViewHolder(view);
case VIEW_TYPE_PROGRESS:
Log.v("view_type_progress","I am in VIEW_TYPE_PROGRESS");
View progressView = LayoutInflater.from(context).inflate(R.layout.progress_loader, viewGroup, false);
return new ProgressViewHolder(progressView);
}
return null;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(MainViewHolder viewHolder, int position) {
RewardItemBO rewardItemBO= rewardArray.get(position);
if(viewHolder instanceof RewardViewHolder)
{
RewardViewHolder rewardViewHolder=(RewardViewHolder) viewHolder;
rewardViewHolder.tvRewardTitle.setText(rewardArray.get(position).getRewardTitle());
rewardViewHolder.tvRewardDescription.setText(rewardArray.get(position).getRewardMessage());
String formatedDate = DateTimeOp.oneFormatToAnother(rewardArray.get(position).getRewardExpiryDate(), Constants.dateFormat18, Constants.dateFormat6);
rewardViewHolder.tvRewardExpiry.setText("Expires " + formatedDate);
if(rewardArray.get(position).getRewardShowRedeem().equals("1"))
{
rewardViewHolder.btnGrey.setVisibility(View.VISIBLE);
rewardViewHolder.btnGrey.setText("Redeemed");
}
else if(rewardArray.get(position).getRewardExpired().equals("1"))
{
rewardViewHolder.btnGrey.setVisibility(View.VISIBLE);
rewardViewHolder.btnGrey.setText("Expired");
}
else
{
rewardViewHolder.btnOrange.setVisibility(View.VISIBLE);
rewardViewHolder.btnOrange.setText("Get Code");
}
}
else if(viewHolder instanceof RewardListViewHolderHeader)
{
RewardListViewHolderHeader holder = (RewardListViewHolderHeader ) viewHolder;
holder.tvHeader.setText(rewardItemBO.getHeaderTitle());
}
else if(viewHolder instanceof ProgressViewHolder)
{
ProgressViewHolder progressViewHolder = (ProgressViewHolder) viewHolder;
progressViewHolder.progressBar.setIndeterminate(true);
}
}
public void addOnTop(ArrayList<RewardItemBO> topItemList) {
Collections.reverse(topItemList);
rewardArray.addAll(0, topItemList);
notifyItemRangeInserted(0, topItemList.size());
}
public interface OnItemClickListener {
public void onItemClick(View view , int position);
}
public void SetOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
#Override
public long getItemId(int position) {
return position;
}
public ArrayList<RewardItemBO> getFilterRewards(ArrayList<RewardItemBO> mainItems){
ArrayList<RewardItemBO> currentRewardList = new ArrayList<RewardItemBO>();
ArrayList<RewardItemBO> pastRewardList = new ArrayList<RewardItemBO>();
ArrayList<RewardItemBO> dummyArray = new ArrayList<>();
for (RewardItemBO rewardItemBO : mainItems) {
try {
//because reward item with progress have everything null in it.
if(rewardItemBO.getRewardExpired()!=null && !rewardItemBO.isShowProgress())
{
int isExpired = Integer.parseInt(rewardItemBO.getRewardExpired());
if(isExpired==1)
pastRewardList.add(rewardItemBO);
else
currentRewardList.add(rewardItemBO);
}
}catch (NumberFormatException e){
e.printStackTrace();
}
}
if(currentRewardList.size()>0){
currentRewardList.add(0, new RewardItemBO(context.getResources().getString(R.string.Current)));
dummyArray.addAll(currentRewardList);
}
if(pastRewardList.size()>0){
pastRewardList.add(0, new RewardItemBO(context.getResources().getString(R.string.Past)));
dummyArray.addAll(pastRewardList);
}
return dummyArray;
}
public void addProgressView()
{
rewardArray.add(new RewardItemBO(true));
//notifyItemChanged(rewardArray.size());
notifyDataSetChanged();
}
public void removeProgressView(){
int position = rewardArray.size() -1;
rewardArray.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, rewardArray.size());
}
public static class RewardListViewHolderHeader extends MainViewHolder {
protected TextView tvHeader;
public RewardListViewHolderHeader (View v) {
super(v);
tvHeader = (TextView) v.findViewById(R.id.header_text);
}
}
public class RewardViewHolder extends MainViewHolder implements View.OnClickListener{
public TextView tvRewardTitle;
public TextView tvRewardDescription;
public TextView tvRewardExpiry;
public Button btnOrange,btnGrey;
public RewardViewHolder(View v) {
super(v);
tvRewardTitle = (TextView) itemView.findViewById(R.id.tv_reward_title);
tvRewardDescription = (TextView) itemView.findViewById(R.id.tv_reward_description);
tvRewardExpiry = (TextView) itemView.findViewById(R.id.tv_reward_expiry_date);
btnOrange = (Button) itemView.findViewById(R.id.btn_item_reward_orange);
btnGrey = (Button) itemView.findViewById(R.id.btn_item_reward_grey);
btnOrange.setOnClickListener(this);
btnGrey.setOnClickListener(this);
}
#Override
public void onClick(View v) {
//Toast.makeText(context, tvName.getText().toString(), Toast.LENGTH_SHORT).show();
if (mItemClickListener != null) {
mItemClickListener.onItemClick(v,getAdapterPosition());
}
}
}
}
I have it clicked and it gets up to it and shows the right getText() method but the setText method is not working...
userAdapter.setOnEntryClickListener(new UserAdapter.OnEntryClickListener() {
#Override
public void onEntryClick(View view, int position) {
DatabaseUser user = dbUsersList.get(position);
TextView clickedView = (TextView) view.findViewById(R.id.userAdapterFollowBtn);
if(view == clickedView) {
if (clickedView.getText().equals("following")) {
Log.d(Constants.DEBUG, " THE CLICK VIEW IS " + clickedView.getText());
//APPLY Following
String txtFollow = "follow";
clickedView.setText(txtFollow);
if (user.getIsChanged() == 0) {
user.setIsChanged(1);
} else {
user.setIsChanged(0);
}
user.setIsType(3);
db.updateFollow(user);
userAdapter.notifyDataSetChanged();
} else {
clickedView.setText("following");
if (user.getIsChanged() == 0) {
user.setIsChanged(1);
} else {
user.setIsChanged(0);
}
user.setIsType(0);
db.updateFollow(user);
userAdapter.notifyDataSetChanged();
}
} else {
Toast.makeText(getApplicationContext(), user.getUsername() + " is selected!", Toast.LENGTH_SHORT).show();
takeToUserProfile(dbUsersList.get(position));
}
}
});
Here is the adapter class:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.MyViewHolder> {
private List<DatabaseUser> dbUsersList, followingList;
private DatabaseHelper db;
private Context context;
private Typeface typeFace, italicTypeface, boldTypeface;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView userAdapterUsername, userAdapterFollowBtn;
public ImageView userAdapterUserPicture;
public MyViewHolder(View view) {
super(view);
userAdapterUsername = (TextView) view.findViewById(R.id.userAdapterUsername);
userAdapterFollowBtn = (TextView) view.findViewById(R.id.userAdapterFollowBtn);
userAdapterUserPicture = (ImageView) view.findViewById(R.id.userAdapterUserPicture);
Log.d(Constants.DEBUG, "IN MY VIEW HOLDER");
view.setOnClickListener(this);
userAdapterFollowBtn.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (mOnEntryClickListener != null) {
Log.d(Constants.DEBUG, "IN On click");
mOnEntryClickListener.onEntryClick(v, getAdapterPosition());
}
}
}
private static OnEntryClickListener mOnEntryClickListener;
public interface OnEntryClickListener {
void onEntryClick(View view, int position);
}
public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
mOnEntryClickListener = onEntryClickListener;
}
public UserAdapter(Context mContext, List<DatabaseUser> usersList, List<DatabaseUser> passedFollowing, Typeface myTypeface, Typeface myTypefaceItalic, Typeface myTypefaceBold) {
context = mContext;
dbUsersList = usersList;
followingList = passedFollowing;
typeFace = myTypeface;
italicTypeface = myTypefaceItalic;
boldTypeface = myTypefaceBold;
Log.d(Constants.DEBUG, "IN MY User ADAPTER CONSTRUCTOR");
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.follow_item, parent, false);
Log.d(Constants.DEBUG, "RETURN ITEM VIEW HOLDER");
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
DatabaseUser user = dbUsersList.get(position);
holder.userAdapterUsername.setTypeface(boldTypeface);
holder.userAdapterUsername.setText(user.getUsername());
final int pos = getItemViewType(position);
//TODO Create pic link
if(containsId(dbUsersList.get(pos), followingList)) {
//Then show following
holder.userAdapterFollowBtn.setText("following");
} else {
//show follow
holder.userAdapterFollowBtn.setText("follow");
}
String userspic = dbUsersList.get(pos).getPicture();
if(userspic == null) {
//SET DEFAULT OR PUT DEFAULT IN XML AND DO NOTHING IT SHOULD SHOW DEFAULT PIC
} else {
//TODO setupUser Pic
String img1 = "http://www.hindustantimes.com/Images/popup/2015/6/kungfu2.jpg";
Picasso.with(context).load(img1).transform(new RoundedTransformation()).into(holder.userAdapterUserPicture);
}
}
#Override
public int getItemCount() {
return dbUsersList.size();
}
public static boolean containsId(DatabaseUser currentUser, List<DatabaseUser> list) {
for (DatabaseUser object : list) {
if (currentUser.getUserId().equals(object.getUserId())) {
return true;
}
}
return false;
}
#Override
public int getItemViewType(int position) {
return position;
}
}
I have done the same in this project, go here and copy this itemclicklistener class:
https://github.com/isaacurbina/MyMovies/blob/c985f28311f25522c7907d090e48dab5fc108c01/app/src/main/java/com/mobileappsco/training/mymovies/Listeners/RecyclerItemClickListener.java
Then on your Activity or Fragment do this with your recyclerview object.
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// HERE GOES YOUR CODE FOR THE CLICK OF THE ITEM
}
})
);
Then you can use the position to reference the original object inside the list of objects that your adapter is using (the list should be public so that you can access it from the Activity or Fragment), or do like me and put a hidden textview with the ID instead of the position that you can get with:
TextView clickedItem = (TextView) view.findViewById(R.id.hidden_id_textview);
int id = clickedItem.getText();
You can also check at the whole project that contains the class that I sent you in the link above. I hope it helps.
Kind regards!
I am able to change the color of the text and background of imageview of the row clicked of my recyclerview in my navigation drawer fragment.
But my problem is after clicking the 4th item,the 1st item also gets selected.Likewise after clicking my 5th item the 2nd item is selected.
Like this:
How do i solve this? So that only one item is selected at a time?
FragmentDrawer.java
public class FragmentDrawer extends Fragment {
private static String TAG = FragmentDrawer.class.getSimpleName();
private RecyclerView recyclerView;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private NavigationDrawerAdapter adapter;
private View containerView;
private static String[] titles = null;
private FragmentDrawerListener drawerListener;
public FragmentDrawer() {
}
public void setDrawerListener(FragmentDrawerListener listener) {
this.drawerListener = listener;
}
public static List<NavDrawerItem> getData() {
List<NavDrawerItem> data = new ArrayList<>();
int[] icons = {R.drawable.ic_home,
R.drawable.ic_upcoming,
R.drawable.ic_saved,
R.drawable.ic_wehappened,
R.drawable.ic_persons,
R.drawable.ic_music,
R.drawable.ic_parties,
R.drawable.ic_art, R.drawable.ic_network, R.drawable.ic_sports};
// preparing navigation drawer items
for (int i = 0; i < titles.length && i < icons.length; i++) {
NavDrawerItem navItem = new NavDrawerItem();
navItem.setTitle(titles[i]);
navItem.setIcon(icons[i]);
data.add(navItem);
}
return data;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// drawer labels
titles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating view layout
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new NavigationDrawerAdapter(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
List<SimpleSectionedRecyclerViewAdapter.Section> sections =
new ArrayList<SimpleSectionedRecyclerViewAdapter.Section>();
//Sections
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(5, "Categories"));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
NavigationDrawerAdapter.selected_item = position;
recyclerView.getAdapter().notifyDataSetChanged();
drawerListener.onDrawerItemSelected(view, position);
mDrawerLayout.closeDrawer(containerView);
}
#Override
public void onLongClick(View view, int position) {
}
}));
SimpleSectionedRecyclerViewAdapter.Section[] dummy = new SimpleSectionedRecyclerViewAdapter.Section[sections.size()];
SimpleSectionedRecyclerViewAdapter mSectionedAdapter = new
SimpleSectionedRecyclerViewAdapter(getContext(), R.layout.section, R.id.section_text, adapter);
mSectionedAdapter.setSections(sections.toArray(dummy));
//Apply this adapter to the RecyclerView
recyclerView.setAdapter(mSectionedAdapter);
return layout;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
toolbar.setAlpha(1 - slideOffset / 2);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static interface ClickListener {
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = 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 && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
public interface FragmentDrawerListener {
public void onDrawerItemSelected(View view, int position);
}
}
NavigationDrawerAdapter.java
public class NavigationDrawerAdapter extends RecyclerView.Adapter<NavigationDrawerAdapter.MyViewHolder> {
List<NavDrawerItem> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
public static int selected_item = 0;
public NavigationDrawerAdapter(Context context, List<NavDrawerItem> data) {
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
}
public void delete(int position) {
data.remove(position);
notifyItemRemoved(position);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.nav_drawer_row, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if(position == selected_item)
{
holder.title.setTextColor(Color.parseColor("#00aaff"));
holder.imgViewIcon.setBackgroundResource(R.drawable.ic_circle);
}
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
holder.imgViewIcon.setImageResource(current.getIcon());
}
#Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
public ImageView imgViewIcon;
public MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
imgViewIcon = (ImageView) itemView.findViewById(R.id.item_icon);
}
}
}
EDIT: SimpleSectionedRecyclerViewAdapter.java
public class SimpleSectionedRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context mContext;
private static final int SECTION_TYPE = 0;
private boolean mValid = true;
private int mSectionResourceId;
private int mTextResourceId;
private LayoutInflater mLayoutInflater;
private RecyclerView.Adapter mBaseAdapter;
private SparseArray<Section> mSections = new SparseArray<Section>();
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSectionResourceId = sectionResourceId;
mTextResourceId = textResourceId;
mBaseAdapter = baseAdapter;
mContext = context;
mBaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onChanged() {
mValid = mBaseAdapter.getItemCount()>0;
notifyDataSetChanged();
}
#Override
public void onItemRangeChanged(int positionStart, int itemCount) {
mValid = mBaseAdapter.getItemCount()>0;
notifyItemRangeChanged(positionStart, itemCount);
}
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
mValid = mBaseAdapter.getItemCount()>0;
notifyItemRangeInserted(positionStart, itemCount);
}
#Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
mValid = mBaseAdapter.getItemCount()>0;
notifyItemRangeRemoved(positionStart, itemCount);
}
});
}
public static class SectionViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public SectionViewHolder(View view,int mTextResourceid) {
super(view);
title = (TextView) view.findViewById(mTextResourceid);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
if (typeView == SECTION_TYPE) {
final View view = LayoutInflater.from(mContext).inflate(mSectionResourceId, parent, false);
return new SectionViewHolder(view,mTextResourceId);
}else{
return mBaseAdapter.onCreateViewHolder(parent, typeView -1);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
if (isSectionHeaderPosition(position)) {
((SectionViewHolder)sectionViewHolder).title.setText(mSections.get(position).title);
}else{
mBaseAdapter.onBindViewHolder(sectionViewHolder,sectionedPositionToPosition(position));
}
}
#Override
public int getItemViewType(int position) {
return isSectionHeaderPosition(position)
? SECTION_TYPE
: mBaseAdapter.getItemViewType(sectionedPositionToPosition(position)) +1 ;
}
public static class Section {
int firstPosition;
int sectionedPosition;
CharSequence title;
public Section(int firstPosition, CharSequence title) {
this.firstPosition = firstPosition;
this.title = title;
}
public CharSequence getTitle() {
return title;
}
}
public void setSections(Section[] sections) {
mSections.clear();
Arrays.sort(sections, new Comparator<Section>() {
#Override
public int compare(Section o, Section o1) {
return (o.firstPosition == o1.firstPosition)
? 0
: ((o.firstPosition < o1.firstPosition) ? -1 : 1);
}
});
int offset = 0; // offset positions for the headers we're adding
for (Section section : sections) {
section.sectionedPosition = section.firstPosition + offset;
mSections.append(section.sectionedPosition, section);
++offset;
}
notifyDataSetChanged();
}
public int positionToSectionedPosition(int position) {
int offset = 0;
for (int i = 0; i < mSections.size(); i++) {
if (mSections.valueAt(i).firstPosition > position) {
break;
}
++offset;
}
return position + offset;
}
public int sectionedPositionToPosition(int sectionedPosition) {
if (isSectionHeaderPosition(sectionedPosition)) {
return RecyclerView.NO_POSITION;
}
int offset = 0;
for (int i = 0; i < mSections.size(); i++) {
if (mSections.valueAt(i).sectionedPosition > sectionedPosition) {
break;
}
--offset;
}
return sectionedPosition + offset;
}
public boolean isSectionHeaderPosition(int position) {
return mSections.get(position) != null;
}
#Override
public long getItemId(int position) {
return isSectionHeaderPosition(position)
? Integer.MAX_VALUE - mSections.indexOfKey(position)
: mBaseAdapter.getItemId(sectionedPositionToPosition(position));
}
#Override
public int getItemCount() {
return (mValid ? mBaseAdapter.getItemCount() + mSections.size() : 0);
}
}
Change the onBindViewHolder method of your NavigationDrawerAdapter.java into this:
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if(position == selected_item) {
holder.title.setTextColor(Color.parseColor("#00aaff"));
holder.imgViewIcon.setBackgroundResource(R.drawable.ic_circle);
} else {
holder.title.setTextColor(Color.parseColor("#00000")); //actually you should set to the normal text color
holder.imgViewIcon.setBackgroundResource(0);
}
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
holder.imgViewIcon.setImageResource(current.getIcon());
}
Simple and Best
Inside Adapter class
int row_index=0;
inside onBindViewHOlder
holder.titleLL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
row_index=position;
notifyDataSetChanged();
}
});
if (row_index==position) {
holder.title.setTextColor(Color.RED);
} else {
holder.title.setTextColor(Color.BLACK);
}
You can use class for Recycler view TouchListener
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
private ClickListener clicklistener;
private GestureDetector gestureDetector;
public RecyclerTouchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener){
this.clicklistener=clicklistener;
gestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child=recycleView.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null){
clicklistener.onLongClick(child,recycleView.getChildAdapterPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child=rv.findChildViewUnder(e.getX(),e.getY());
RecyclerView.ViewHolder viewHolder=rv.findContainingViewHolder(child);
if(child!=null && clicklistener!=null && gestureDetector.onTouchEvent(e)){
clicklistener.onClick(child,rv.getChildAdapterPosition(child),viewHolder);
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
Implement an Interface
public interface ClickListener{
public void onClick(View view, int position,RecyclerView.ViewHolder viewHolder);
public void onLongClick(View view, int position);
}
And in your Main Activity (Here I set Image resource You can set as You like ,Any thing)
Create an arraylist named "selected" as Integer and add following code as OnClickListener
recyclerViewSchedule.addOnItemTouchListener(new RecyclerTouchListener(this,
recyclerViewSchedule, new ClickListener() {
#Override
public void onClick(View view, final int position, RecyclerView.ViewHolder v) {
//Values are passing to activity & to fragment as well
if(!selected.contains(position))
{
selected.add(position);
((ScheduleAdapter.MyHolder) v).txtImage.setBackgroundColor(getResources().getColor(R.color.colorAccent));
}else {
((ScheduleAdapter.MyHolder) v).txtImage.setBackgroundColor(getResources().getColor(R.color.colorTransparent));
selected.remove(new Integer(position));
}
Toast.makeText(ScheduleActivity.this, "Single Click on position :"+position,
Toast.LENGTH_SHORT).show();
}
Toast.makeText(ScheduleActivity.this, "Single Click on position :"+position,
Toast.LENGTH_SHORT).show();
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(ScheduleActivity.this, "Long press on position :"+position,
Toast.LENGTH_LONG).show();
}
}));
The txtImage I specified here is from RecyclerAdapter,Replace it with Your View
Happy Coding :-)
most of the answers for such a question, are about to Override Onclick in onBindViewHolder or implementing an interface for clicking in recycler view. but as we all know, onBindViewHolder is called as your views are populated during scrolling. Thus, you will have numerous calls to setOnClickListener so it is not an efficient way and also implementing interface is not as easy as the answer I got.
here is how you can access selecting items in recycler view and change its background or do what ever you want when an item is selected .
in your ViewHolder constructor use setOnTouchListener for itemView (the argument of constructor) in this way
itemView.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (v.getTag() == null) {
v.setTag(true);
v.setBackgroundColor(Color.parseColor("#F31807"));
}
else {
v.setBackgroundColor(Color.TRANSPARENT);
v.setTag(null);
}
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
//default color
v.setBackgroundColor(Color.TRANSPARENT);
}
return true;
});
We use ACTION_UP for check if user pressed the item and after that we save a boolean in view's flag so that we can press every items how many times we want and see the color is changing. ACTION_MOVE if block is for prevent selecting items when scrolling the recycler view. if you see that selecting one item is affecting another items selection, you can use this answer:
issue : RecyclerView messed up data when scrolling
in the end if you are curious about why we return true in method see this video to understand.
tutorial on OnTouchListener And Motionevent
I have tried many different approaches but in the end, the solution that worked for me is
like first I was doing this
binding.download.setOnClickListener {
binding.download.visibility = View.GONE
binding.saved.visibility = View.VISIBLE
}
this was not working for me but after the below change
Instead of changing the color or visibility in onBindViewHolder, make a function in ViewHolder class and call it from onBindViewHolder
class ViewHolder(var binding: ImageRowBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(uri: Uri, mContext: Context) {
binding.download.setOnClickListener {
binding.download.visibility = View.GONE
binding.saved.visibility = View.VISIBLE
}
}
}
and calling this bind method from onBindViewHolder like this
holder.bind(items[position].uri, mContext)
works best for me