ナビゲーションドロワー内でrecyclerViewを使用しており、このライブラリを使用しています Twoway-view クリックと選択のサポートを取得しています。
それは完璧に機能し、各位置のOnClickメソッド内で問題なくテキストとアイコンの色を変更できます。
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();
}
});
問題は、そのメソッドのように最初のアイテムにアクセスしたいのですが、その前に(最初に選択したアイテムを異なる色で設定するなど)です。
しかし、OnClickメソッドの外部で最初のアイテムを取得しようとするとクラッシュ(null参照)が発生します:
ImageView imageViewDrawerIcon = (ImageView) recyclerViewDrawer.getChildAt(0).findViewById(R.id.imageViewDrawerIcon);
すべてのコード:
// 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();
}
});
私はこれで最終的に解決しました( ソース ):
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);
}
});
ちなみに、誰かがもっと良い解決策を持っているなら、私はそれを知りたいです。
私の場合、それは魅力のように機能します
View viewItem = recycleView.getLayoutManager().findViewByPosition(position);
View icon = viewItem.findViewById(R.id.view);
これは私のために働いた。
recyclerView.post(new Runnable() {
@Override
public void run() {
View viewItem = recycleView.getLayoutManager().findViewByPosition(position);
View icon = viewItem.findViewById(R.id.view);
}
});
代わりに findViewHolderForAdapterPosition() または findViewByPosition( )を使用して、そのインデックスでルートビューを検索します。ただし、データを確実にロードする方法はあなた次第です。
findViewByPosition
はLayoutManager
のメソッドであり、すべてのLayoutManagerで機能します。
したがって、recycleView.getLayoutManager()
およびfindViewByPosition(pos)
を使用できます。
また、recyclerView.findViewHolderForAdapterPosition(pos)
も機能します。
詳細については、これを参照してください RecyclerView-特定の位置でビューを取得します