9

I am using a recyclerView inside my navigation drawer and I am using this library Twoway-view to get click and selection support.

It works perfectly and I can change the color of the text and the icons without problems inside OnClick method for each position:

itemClickSupport.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() { @Override public void onItemClick(RecyclerView parent, View view, int position, long id) { TypedValue typedValue = new TypedValue(); MainActivity.this.getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true); final int color = typedValue.data; //TODO Icon and text colors for (int i = 0; i < drawerTitles.length; i++){ if (i == position){ ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.imageViewDrawerIcon); TextView textViewDrawerTitle = (TextView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.textViewDrawerItemTitle); imageViewDrawerIcon.setColorFilter(color); if(Build.VERSION.SDK_INT > 15){ imageViewDrawerIcon.setImageAlpha(255); }else{ imageViewDrawerIcon.setAlpha(255); } textViewDrawerTitle.setTextColor(color); RelativeLayout relativeLayoutDrawerItem = (RelativeLayout) recyclerViewDrawer.getChildAt(i).findViewById(R.id.relativeLayoutDrawerItem); relativeLayoutDrawerItem.setFocusableInTouchMode(true); }else{ ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.imageViewDrawerIcon); TextView textViewDrawerTitle = (TextView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.textViewDrawerItemTitle); imageViewDrawerIcon.setColorFilter(getResources().getColor(R.color.md_text)); if(Build.VERSION.SDK_INT > 15){ imageViewDrawerIcon.setImageAlpha(138); }else{ imageViewDrawerIcon.setAlpha(138); } textViewDrawerTitle.setTextColor(getResources().getColor(R.color.md_text)); RelativeLayout relativeLayoutDrawerItem = (RelativeLayout) recyclerViewDrawer.getChildAt(i).findViewById(R.id.relativeLayoutDrawerItem); relativeLayoutDrawerItem.setFocusableInTouchMode(false); } } //TODO Fragments (closedrawers before setfragment) final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Do something after some time } }, 250); mDrawerLayout.closeDrawers(); } }); 

The problem is that I want to access to the first item like in that method, but before it (to set the first item selected, with different color, etc).

But I get a crash (null reference) when I try to get the first item outside OnClick method:

ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(0).findViewById(R.id.imageViewDrawerIcon); 

All code:

// Setup RecyclerView inside drawer recyclerViewDrawer = (RecyclerView) findViewById(R.id.recyclerViewDrawer); recyclerViewDrawer.setHasFixedSize(true); recyclerViewDrawer.setLayoutManager(new LinearLayoutManager(MainActivity.this)); ArrayList<DrawerItem> drawerItems = new ArrayList<>(); final String[] drawerTitles = getResources().getStringArray(R.array.drawer); final TypedArray drawerIcons = getResources().obtainTypedArray(R.array.drawerIcons); for (int i = 0; i < drawerTitles.length; i++) { drawerItems.add(new DrawerItem(drawerTitles[i], drawerIcons.getDrawable(i))); } drawerIcons.recycle(); adapterDrawer = new DrawerAdapter(drawerItems); recyclerViewDrawer.setAdapter(adapterDrawer); // Here is the problem ImageView imageViewDrawerIcon2 = (ImageView) recyclerViewDrawer.getChildAt(0).findViewById(R.id.imageViewDrawerIcon); // RecyclerView item listener. ItemClickSupport itemClickSupport = ItemClickSupport.addTo(recyclerViewDrawer); itemClickSupport.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() { @Override public void onItemClick(RecyclerView parent, View view, int position, long id) { TypedValue typedValue = new TypedValue(); MainActivity.this.getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true); final int color = typedValue.data; //TODO Icon and text colors for (int i = 0; i < drawerTitles.length; i++){ if (i == position){ ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.imageViewDrawerIcon); TextView textViewDrawerTitle = (TextView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.textViewDrawerItemTitle); imageViewDrawerIcon.setColorFilter(color); if(Build.VERSION.SDK_INT > 15){ imageViewDrawerIcon.setImageAlpha(255); }else{ imageViewDrawerIcon.setAlpha(255); } textViewDrawerTitle.setTextColor(color); RelativeLayout relativeLayoutDrawerItem = (RelativeLayout) recyclerViewDrawer.getChildAt(i).findViewById(R.id.relativeLayoutDrawerItem); relativeLayoutDrawerItem.setFocusableInTouchMode(true); }else{ ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.imageViewDrawerIcon); TextView textViewDrawerTitle = (TextView) recyclerViewDrawer.getChildAt(i).findViewById(R.id.textViewDrawerItemTitle); imageViewDrawerIcon.setColorFilter(getResources().getColor(R.color.md_text)); if(Build.VERSION.SDK_INT > 15){ imageViewDrawerIcon.setImageAlpha(138); }else{ imageViewDrawerIcon.setAlpha(138); } textViewDrawerTitle.setTextColor(getResources().getColor(R.color.md_text)); RelativeLayout relativeLayoutDrawerItem = (RelativeLayout) recyclerViewDrawer.getChildAt(i).findViewById(R.id.relativeLayoutDrawerItem); relativeLayoutDrawerItem.setFocusableInTouchMode(false); } } //TODO Fragments (closedrawers before setfragment) final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Do something after some time } }, 250); mDrawerLayout.closeDrawers(); } }); 
1

6 Answers 6

20

In my case it,is work like a charm

View viewItem = recycleView.getLayoutManager().findViewByPosition(position); View icon = viewItem.findViewById(R.id.view); 
Sign up to request clarification or add additional context in comments.

3 Comments

Gives warning "Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView"
it returns null
Seems it works only if item is visible right now, useless. Even if I call layoutManager.scrollToPosition(position) before calling findViewByPosition(position) it still doesn't work
9

I solved finally with this (source):

recyclerViewDrawer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(0).findViewById(R.id.imageViewDrawerIcon); TextView textViewDrawerTitle = (TextView) recyclerViewDrawer.getChildAt(0).findViewById(R.id.textViewDrawerItemTitle); imageViewDrawerIcon.setColorFilter(color); if (Build.VERSION.SDK_INT > 15) { imageViewDrawerIcon.setImageAlpha(255); } else { imageViewDrawerIcon.setAlpha(255); } textViewDrawerTitle.setTextColor(color); RelativeLayout relativeLayoutDrawerItem = (RelativeLayout) recyclerViewDrawer.getChildAt(0).findViewById(R.id.relativeLayoutDrawerItem); relativeLayoutDrawerItem.setFocusableInTouchMode(true); // unregister listener (this is important) recyclerViewDrawer.getViewTreeObserver().removeGlobalOnLayoutListener(this); } }); 

By the way, if someone have a better solution I would like to know it.

1 Comment

We're still getting some instances of getChildViiew(0) being null with this approach. I personally can't reproduce it. Using setAdapter triggers the child view inflation so ideally there would be a callback that is called when the child view is inflated and added to the RecyclerView
8

This worked for me.

recyclerView.post(new Runnable() { @Override public void run() { View viewItem = recycleView.getLayoutManager().findViewByPosition(position); View icon = viewItem.findViewById(R.id.view); } }); 

2 Comments

Nice, this worked perfectly for getting the displayed children and viewholders using getChildAt() and getChildViewHolder()
Of note is that you can't manipulate many UI elements with this, since you're working from a different thread. You'll have to set up inter-thread communication.
5

I would use findViewHolderForAdapterPosition() or findViewByPosition() instead to find the root view at that index. The way you ensure the data is loaded is up to you, however.

Comments

1

findViewByPosition is a method of LayoutManager, which works with all LayoutManagers.

So you can use recycleView.getLayoutManager() and findViewByPosition(pos).

Also recyclerView.findViewHolderForAdapterPosition(pos) works too.

For more information, look at this RecyclerView - Get view at particular position

Comments

0

You can get ItemView from recyclerView's holder using below code:

val holder = yourRecyclerView.findViewHolderForAdapterPosition(position) if (holder != null) { val rootView = holder.itemView //do your code here } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.