Java RecyclerView - 获取特定位置的视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33784369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:02:13  来源:igfitidea点击:

RecyclerView - Get view at particular position

javaandroidandroid-recyclerviewwidgetposition

提问by Vamsi Challa

I have an activity with a RecyclerViewand an ImageView. I am using the RecyclerViewto show a list of images horizontally. When I click on an image in the RecyclerViewthe ImageViewin the activity should show a bigger picture of the image. So far everything works fine.

我有一个带有 aRecyclerView和 an的活动ImageView。我正在使用RecyclerView来水平显示图像列表。当我点击在图像上RecyclerViewImageView在活动中应显示图像的大局观。到目前为止一切正常。

Now there are two more ImageButtonsin the activity: imageButton_leftand imageButton_right. When I click on imageButton_left, the image in the ImageViewshould turn left and also, the thumbnail in the RecyclerViewshould reflect this change. Similar is the case with imageButton_right.

现在活动中还有两个ImageButtonsimageButton_leftimageButton_right。当我点击 时imageButton_left, 中的图像ImageView应该向左转,并且 中的缩略图RecyclerView应该反映这种变化。与 的情况类似imageButton_right

I am able to rotate the ImageView. But, how can I rotate the thumbnail in the RecyclerView? How can I get the ViewHolder's ImageView?

我能够旋转ImageView. 但是,如何在RecyclerView. 我怎样才能得到ViewHolderImageView

Code:

代码:

Activity XML:

活动 XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/original_image"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:scaleType="fitXY"
            android:src="@drawable/image_not_available_2" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center_horizontal"
            android:orientation="horizontal">


            <ImageButton
                android:id="@+id/imageButton_left"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="20dp"
                android:background="@drawable/rotate_left_icon" />

            <ImageButton
                android:id="@+id/imageButton_right"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/rotate_right_icon" />

        </LinearLayout>
    </LinearLayout>
</LinearLayout>

My Activity Code:

我的活动代码:

public class SecondActivity extends AppCompatActivity implements IRecyclerViewClickListener {


    RecyclerView mRecyclerView;
    LinearLayoutManager mLayoutManager;
    RecyclerViewAdapter mRecyclerViewAdapter;
    List<String> urls = new ArrayList<String>();
    ImageView mOriginalImageView;
    ImageButton mLeftRotate, mRightRotate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        urls.clear();

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mLayoutManager = new LinearLayoutManager(this, android.support.v7.widget.LinearLayoutManager.HORIZONTAL, false);
        mLayoutManager.setOrientation(android.support.v7.widget.LinearLayoutManager.HORIZONTAL);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerViewAdapter = new RecyclerViewAdapter(this, urls);
        mRecyclerView.setAdapter(mRecyclerViewAdapter);

        mOriginalImageView = (ImageView) findViewById(R.id.original_image);
        mLeftRotate = (ImageButton) findViewById(R.id.imageButton_left);
        mLeftRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOriginalImageView.setRotation(mOriginalImageView.getRotation() - 90);
            }
        });


        mRightRotate = (ImageButton) findViewById(R.id.imageButton_right);
        mRightRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOriginalImageView.setRotation(mOriginalImageView.getRotation() + 90);
            }
        });

        Intent intent = getIntent();
        if (intent != null) {

            String portfolio = intent.getStringExtra("portfolio");

            try {

                JSONArray jsonArray = new JSONArray(portfolio);

                for (int i = 0; i < jsonArray.length(); i++) {

                    JSONObject jsonObject = jsonArray.getJSONObject(i);

                    String url = jsonObject.getString("url");
                    urls.add(url);
                }

                Log.d(Const.DEBUG, "URLs: " + urls.toString());

                mRecyclerViewAdapter.notifyDataSetChanged();

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }


    @Override
    public void onItemClick(int position) {
        Picasso.with(this).load(urls.get(position)).into(mOriginalImageView);
    }
}

My Custom Adapter for RecyclerView:

我的 RecyclerView 自定义适配器:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    Context context;
    List<String> mUrls = new ArrayList<String>();

    IRecyclerViewClickListener mIRecyclerViewClickListener;

    public int position;

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }



    public RecyclerViewAdapter(Context context, List<String> urls) {
        this.context = context;
        this.mUrls.clear();
        this.mUrls = urls;

        Log.d(Const.DEBUG, "Urls Size: " + urls.size());
        Log.d(Const.DEBUG, urls.toString());

        if (context instanceof IRecyclerViewClickListener)
            mIRecyclerViewClickListener = (IRecyclerViewClickListener) context;
        else
            Log.d(Const.DEBUG, "Implement IRecyclerViewClickListener in Activity");
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_recyclerview, parent, false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Picasso.with(context).load(mUrls.get(position)).into(holder.mImageView);
    }

    @Override
    public int getItemCount() {
        return mUrls.size();
    }


    public void rotateThumbnail() {


    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public ImageView mImageView;
        public View v;

        public ViewHolder(View v) {
            super(v);
            v.setTag(getAdapterPosition());
            v.setOnClickListener(this);
            this.mImageView = (ImageView) v.findViewById(R.id.image);
        }

        @Override
        public void onClick(View v) {
            this.v = v;
            mIRecyclerViewClickListener.onItemClick(getAdapterPosition());
        }
    }


}

采纳答案by stan0

I suppose you are using a LinearLayoutManagerto show the list. It has a nice method called findViewByPositionthat

我想您正在使用 aLinearLayoutManager来显示列表。它有所谓的一个很好的方法findViewByPosition

Finds the view which represents the given adapter position.

查找表示给定适配器位置的视图。

All you need is the adapter position of the item you are interested in.

您所需要的只是您感兴趣的项目的适配器位置。

edit: as noted by Paul Woitaschekin the comments, findViewByPositionis a method of LayoutManagerso it would work with all LayoutManagers (i.e. StaggeredGridLayoutManager, etc.)

编辑:正如Paul Woitaschek在评论中所指出的,findViewByPosition是一种方法,LayoutManager因此它适用于所有 LayoutManagers(即StaggeredGridLayoutManager,等)

回答by Scott Biggs

This is what you're looking for.

这就是你要找的

I had this problem too. And like you, the answer is very hard to find. But there IS an easy way to get the ViewHolder from a specific position (something you'll probably do a lot in the Adapter).

我也有这个问题。和你一样,答案很难找到。但是有一种简单的方法可以从特定位置获取 ViewHolder(您可能会在 Adapter 中做很多事情)。

myRecyclerView.findViewHolderForAdapterPosition(pos);

myRecyclerView.findViewHolderForAdapterPosition(pos);

NOTE:If the View has been recycled, this will return null. Thanks to Michael for quickly catching my important omission.

注意:如果 View 已被回收,这将返回null. 感谢迈克尔迅速发现我的重要遗漏。

回答by Horatio

If you want the View, make sure to access the itemViewproperty of the ViewHolder like so: myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;

如果需要View,请确保itemView像这样访问ViewHolder的属性:myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;

回答by Vikash Kumar Tiwari

You can use use both

您可以同时使用

recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition)and recyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition). Be sure that RecyclerView view uses two type of positions

recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition)recyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition)。确保 RecyclerView 视图使用两种类型的位置

Adapter position : Position of an item in the adapter. This is the position from the Adapter's perspective. Layout position : Position of an item in the latest layout calculation. This is the position from the LayoutManager's perspective. You should use getAdapterPosition()for findViewHolderForAdapterPosition(adapterPosition)and getLayoutPosition()for findViewHolderForLayoutPosition(layoutPosition).

适配器位置 :项目在适配器中的位置。这是从适配器的角度来看的位置。布局位置 : 项目在最新布局计算中的位置。这是从 LayoutManager 的角度来看的位置。您应该使用getAdapterPosition()forfindViewHolderForAdapterPosition(adapterPosition)getLayoutPosition()for findViewHolderForLayoutPosition(layoutPosition)

Take a member variable to hold previously selected item position in recyclerview adapter and other member variable to check whether user is clicking for first time or not.

取一个成员变量来保存之前在 recyclerview 适配器中选择的项目位置和其他成员变量来检查用户是否第一次点击。

Sample code and screen shots are attached for more information at the bottom.

底部附有示例代码和屏幕截图以获取更多信息。

public class MainActivity extends AppCompatActivity {     

private RecyclerView mRecyclerList = null;    
private RecyclerAdapter adapter = null;    

@Override    
protected void onCreate(Bundle savedInstanceState) {    
    super.onCreate(savedInstanceState);    
    setContentView(R.layout.activity_main);    

    mRecyclerList = (RecyclerView) findViewById(R.id.recyclerList);    
}    

@Override    
protected void onStart() {    
    RecyclerView.LayoutManager layoutManager = null;    
    String[] daysArray = new String[15];    
    String[] datesArray = new String[15];    

    super.onStart();    
    for (int i = 0; i < daysArray.length; i++){    
        daysArray[i] = "Sunday";    
        datesArray[i] = "12 Feb 2017";    
    }    

    adapter = new RecyclerAdapter(mRecyclerList, daysArray, datesArray);    
    layoutManager = new LinearLayoutManager(MainActivity.this);    
    mRecyclerList.setAdapter(adapter);    
    mRecyclerList.setLayoutManager(layoutManager);    
}    
}    


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyCardViewHolder>{          

private final String TAG = "RecyclerAdapter";        
private Context mContext = null;        
private TextView mDaysTxt = null, mDateTxt = null;    
private LinearLayout mDateContainerLayout = null;    
private String[] daysArray = null, datesArray = null;    
private RecyclerView mRecyclerList = null;    
private int previousPosition = 0;    
private boolean flagFirstItemSelected = false;    

public RecyclerAdapter(RecyclerView mRecyclerList, String[] daysArray, String[] datesArray){    
    this.mRecyclerList = mRecyclerList;    
    this.daysArray = daysArray;    
    this.datesArray = datesArray;    
}    

@Override    
public MyCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {    
    LayoutInflater layoutInflater = null;    
    View view = null;    
    MyCardViewHolder cardViewHolder = null;    
    mContext = parent.getContext();    
    layoutInflater = LayoutInflater.from(mContext);    
    view = layoutInflater.inflate(R.layout.date_card_row, parent, false);    
    cardViewHolder = new MyCardViewHolder(view);    
    return cardViewHolder;    
}    

@Override    
public void onBindViewHolder(MyCardViewHolder holder, final int position) {    
    mDaysTxt = holder.mDaysTxt;    
    mDateTxt = holder.mDateTxt;    
    mDateContainerLayout = holder.mDateContainerLayout;    

    mDaysTxt.setText(daysArray[position]);    
    mDateTxt.setText(datesArray[position]);    

    if (!flagFirstItemSelected){    
        mDateContainerLayout.setBackgroundColor(Color.GREEN);    
        flagFirstItemSelected = true;    
    }else {    
        mDateContainerLayout.setBackground(null);    
    }    
}    

@Override    
public int getItemCount() {    
    return daysArray.length;    
}    

class MyCardViewHolder extends RecyclerView.ViewHolder{    
    TextView mDaysTxt = null, mDateTxt = null;    
    LinearLayout mDateContainerLayout = null;    
    LinearLayout linearLayout = null;    
    View view = null;    
    MyCardViewHolder myCardViewHolder = null;    

    public MyCardViewHolder(View itemView) {    
        super(itemView);    
        mDaysTxt = (TextView) itemView.findViewById(R.id.daysTxt);    
        mDateTxt = (TextView) itemView.findViewById(R.id.dateTxt);    
        mDateContainerLayout = (LinearLayout) itemView.findViewById(R.id.dateContainerLayout);    

        mDateContainerLayout.setOnClickListener(new View.OnClickListener() {    
            @Override    
            public void onClick(View v) {    
                LinearLayout linearLayout = null;    
                View view = null;    

                if (getAdapterPosition() == previousPosition){    
                    view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;    
                    linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);    
                    linearLayout.setBackgroundColor(Color.GREEN);    
                    previousPosition = getAdapterPosition();    

                }else {    
                    view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;    
                    linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);    
                    linearLayout.setBackground(null);    

                    view = mRecyclerList.findViewHolderForAdapterPosition(getAdapterPosition()).itemView;    
                    linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);    
                    linearLayout.setBackgroundColor(Color.GREEN);    
                    previousPosition = getAdapterPosition();    
                }    
            }    
        });    
    }    
}       

} first element selectedsecond element selected and previously selected item becomes unselectedfifth element selected and previously selected item becomes unselected

} first element selectedsecond element selected and previously selected item becomes unselectedfifth element selected and previously selected item becomes unselected

回答by Tarun Umath

You can make ArrayList of ViewHolder :

您可以制作 ViewHolder 的 ArrayList :

 ArrayList<MyViewHolder> myViewHolders = new ArrayList<>();
 ArrayList<MyViewHolder> myViewHolders2 = new ArrayList<>();

and, all store ViewHolder(s) in the list like :

并且,所有将 ViewHolder(s) 存储在列表中,例如:

 @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        final String str = arrayList.get(position);

        myViewHolders.add(position,holder);
}

and add/remove other ViewHolder in the ArrayList as per your requirement.

并根据您的要求在 ArrayList 中添加/删除其他 ViewHolder。

回答by mut tony

You can as well do this, this will help when you want to modify a view after clicking a recyclerview position item

您也可以这样做,这将有助于您在单击 recyclerview 位置项后想要修改视图

@Override
public void onClick(View view, int position) {

            View v =  rv_notifications.getChildViewHolder(view).itemView;
            TextView content = v.findViewById(R.id.tv_content);
            content.setText("Helloo");

        }

回答by Sunday G Akinsete

You can get a view for a particular position on a recyclerview using the following

您可以使用以下方法获取回收站视图上特定位置的视图

int position = 2;
RecyclerView.ViewHolder viewHolder = recyclerview.findViewHolderForItemId(position);
View view = viewHolder.itemView;
ImageView imageView = (ImageView)view.findViewById(R.id.imageView);

回答by Konstantin Konopko

Keep in mind that you have to wait until adapter will added to list, then you can try to getting view by position

请记住,您必须等到适配器添加到列表中,然后才能尝试按位置获取视图

final int i = 0;
recyclerView.setAdapter(adapter);
recyclerView.post(new Runnable() {
    @Override
    public void run() {
        View view = recyclerView.getLayoutManager().findViewByPosition(i);
    }
});

回答by Mayank Sharma

You can simply use "findViewHolderForAdapterPosition" method of recycler view and you will get a viewHolder object from that then typecast that viewholder into your adapter viewholder so you can directly access your viewholder's views

您可以简单地使用回收器视图的“ findViewHolderForAdapterPosition”方法,您将从那里获得一个 viewHolder 对象,然后将该视图持有者类型转换为您的适配器视图持有者,以便您可以直接访问您的视图持有者的视图

following is the sample code for kotlin

以下是 kotlin 的示例代码

 val viewHolder = recyclerView.findViewHolderForAdapterPosition(position)
 val textview=(viewHolder as YourViewHolder).yourTextView

回答by Chirag Prajapati

To get specific view from recycler view list OR show error at edittext of recycler view.

从回收者视图列表中获取特定视图或在回收者视图的编辑文本中显示错误。

private void popupErrorMessageAtPosition(int itemPosition) {

    RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(itemPosition);
    View view = viewHolder.itemView;
    EditText etDesc = (EditText) view.findViewById(R.id.et_description);
    etDesc.setError("Error message here !");
}