RecyclerView – 在特定位置获取视图

我有一个RecyclerView和一个ImageView 。 我正在使用RecyclerView来水平显示图像列表。 当我点击RecyclerViewImageView时,活动中的ImageView应该会显示更大的图像。 到目前为止一切正常。

现在活动中还有两个ImageButtonsimageButton_leftimageButton_right 。 当我点击imageButton_leftImageView中的ImageView应该向左转,而RecyclerView的缩略图也应该反映这个改变。 与imageButton_right类似。

我能够旋转ImageView 。 但是,如何在RecyclerView旋转缩略图? 我怎样才能得到ViewHolderImageView

码:

活动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> 

我的活动代码:

 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); } } 

我的自定义适配器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()); } } } 

我想你正在使用一个LinearLayoutManager来显示列表。 它有一个很好的方法叫做findViewByPosition

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

所有你需要的是你感兴趣的物品的适配器位置。

编辑 :如注释Paul Woitaschek所述, findViewByPositionLayoutManager一个方法,所以它可以和所有的LayoutManagers(即StaggeredGridLayoutManager等)一起工作。

这是你要找的

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

myRecyclerView.findViewHolderForAdapterPosition(pos);

注意:如果视图已被回收,这将返回null 。 感谢迈克尔赶上我的重要遗漏。

如果你想View ,请确保访问ViewHolder的itemView属性,如下所示: myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;

你可以使用两者

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

适配器位置:适配器中物品的位置。 这是从适配器的angular度来看的。 布局位置:项目在最新布局计算中的位置。 这是从LayoutManager的angular度来看的。 对于findViewHolderForAdapterPosition(adapterPosition) ,应该使用getAdapterPosition()对于findViewHolderForAdapterPosition(adapterPosition) ,应该使用getLayoutPosition() findViewHolderForLayoutPosition(layoutPosition)

取一个成员variables来保存recyclerview adapter和其他成员variables中以前select的项目位置,以检查用户是否第一次点击。

示例代码和屏幕截图附在底部的更多信息。

 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(); } } }); } } 

} 选择第一个元素 选择的第二个元素和先前选择的项目变为未选中 选择的第五个元素和先前选择的项目变为未选中