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
RecyclerView - Get view at particular position
提问by Vamsi Challa
I have an activity with a RecyclerView
and an ImageView
. I am using the RecyclerView
to show a list of images horizontally. When I click on an image in the RecyclerView
the ImageView
in the activity should show a bigger picture of the image. So far everything works fine.
我有一个带有 aRecyclerView
和 an的活动ImageView
。我正在使用RecyclerView
来水平显示图像列表。当我点击在图像上RecyclerView
的ImageView
在活动中应显示图像的大局观。到目前为止一切正常。
Now there are two more ImageButtons
in the activity: imageButton_left
and imageButton_right
. When I click on imageButton_left
, the image in the ImageView
should turn left and also, the thumbnail in the RecyclerView
should reflect this change. Similar is the case with imageButton_right
.
现在活动中还有两个ImageButtons
:imageButton_left
和imageButton_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
. 我怎样才能得到ViewHolder
的ImageView
?
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 LinearLayoutManager
to show the list. It has a nice method called findViewByPosition
that
我想您正在使用 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, findViewByPosition
is a method of LayoutManager
so 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 itemView
property 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();
}
}
});
}
}
回答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 !");
}