RecyclerView – 在特定位置获取视图
我有一个RecyclerView
和一个ImageView
。 我正在使用RecyclerView
来水平显示图像列表。 当我点击RecyclerView
的ImageView
时,活动中的ImageView
应该会显示更大的图像。 到目前为止一切正常。
现在活动中还有两个ImageButtons
: imageButton_left
和imageButton_right
。 当我点击imageButton_left
, ImageView
中的ImageView
应该向左转,而RecyclerView
的缩略图也应该反映这个改变。 与imageButton_right
类似。
我能够旋转ImageView
。 但是,如何在RecyclerView
旋转缩略图? 我怎样才能得到ViewHolder
的ImageView
?
码:
活动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所述, findViewByPosition
是LayoutManager
一个方法,所以它可以和所有的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(); } } }); } }
}