回收视图-获取特定位置的视图

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

现在又有两个 ImageButtons在活动中: imageButton_leftimageButton_right。当我点击 imageButton_left,在 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);
}
}

返回文章页面我的自定义适配器:

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




}
233898 次浏览

我假设您使用的是 LinearLayoutManager来显示列表

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

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

编辑 : 正如 Paul Woitaschek在评论中指出的那样,findViewByPositionLayoutManager的一种方法,因此它可以与所有 LayoutManager (即 StaggeredGridLayoutManager等)一起工作

这就是你要找的。

我也有这个问题。和你一样,答案很难找。但是有一个简单的方法可以从特定的位置获得 ViewHolder (你可能会在适配器中做很多工作)。

myRecyclerView.findViewHolderForAdapterPosition(pos);

注意: 如果视图已被回收,这将返回 null。感谢迈克尔迅速发现了这一疏漏。此外,如果用户正在快速滚动,那么即使在获得这个 ViewHolder 之后,视图也可以被回收,从而导致各种各样的问题。因此,在使用这种技术时要小心,特别是如果您正在做一些相对较慢的工作,比如更改视图的外观。

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

你可以两者都用

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

适配器位置 : 项目在适配器中的位置。这是从适配器的角度来看的位置。

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

在回收视图适配器和其他成员变量中使用一个成员变量来保持先前选定的项目位置,以检查用户是否第一次单击。

示例代码和屏幕截图附在底部,以获得更多信息。

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 selected second element selected and previously selected item becomes unselected fifth element selected and previously selected item becomes unselected

您可以创建 ViewHolder 的 ArrayList:

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

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

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


myViewHolders.add(position,holder);
}

并根据您的要求添加/删除数组列表中的其他 ViewHolder。

您也可以这样做,这将有助于您在单击一个回收视图位置项后修改视图

@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");


}

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

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

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

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

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

下面是 Kotlin 的示例代码

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

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

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

要从回收视图的特定位置获取视图,您需要在将返回回收视图的回收视图对象上调用 findViewHolderForAdapterposition (position)。视图持有人

通过 itemView,您可以访问位于特定位置的所有视图

RecyclerView.ViewHolder rv_view = recyclerView.findViewHolderForAdapterPosition(position);


ImageView iv_wish = rv_view.itemView.findViewById(R.id.iv_item);

如果每次尝试获取带有任何 int 位置的视图时都使用 null,那么尝试向适配器添加一个新的构造函数参数,例如:

class RecyclerViewTableroAdapter(
private val fichas: Array<MFicha?>,
private val activity: View.OnClickListener,
private val indicesGanadores:MutableList<Int>
) : RecyclerView.Adapter<RecyclerViewTableroAdapter.ViewHolder>() {
//CODE
}

如果我的游戏获胜,我添加了指数 Ganadores 来为我的背景着色。

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//CODE
if(indicesGanadores.contains(position)){
holder.cardViewFicha.setCardBackgroundColor((activity as MainActivity).resources.getColor(R.color.DarkGreen))
}
//MORE CODE
}

如果我不需要给背景上色,我只需要发送一个空的可变列表,如下所示:

binding.recyclerViewMain.adapter = RecyclerViewTableroAdapter(fichasTablero, this@MainActivity, mutableListOf<Int>())

编程愉快。

你可以在下面使用

mRecyclerview.getChildAt(pos);

回收视图-获取特定位置的视图。 //int = 位置; 这行代码对我很有用。

  @Override
public void onBindViewHolder(@NonNull @org.jetbrains.annotations.NotNull QuizAdapter.MyViewHolder holder, int position) {


final QuizModel tmodel = modellist.get(position);
holder.tv_question.setText(tmodel.getQuestion());
holder.tv_option_One.setText(tmodel.getOptionA());
holder.tv_option_two.setText(tmodel.getOptionB());
holder.tv_option_three.setText(tmodel.getOptionC());
holder.tv_option_four.setText(tmodel.getOptionD());
holder.tv_option_five.setText(tmodel.getOptionE());
holder.ll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


int is = position;
Toast.makeText(v.getContext(), "count" + is, Toast.LENGTH_LONG).show();


Intent i = new Intent(context, DetailsQuizActivity.class);
i.putExtra("question", tmodel.getQuestion());
i.putExtra("option_a", tmodel.getOptionA());
i.putExtra("option_b", tmodel.getOptionB());
i.putExtra("option_c", tmodel.getOptionC());
i.putExtra("option_d", tmodel.getOptionD());
i.putExtra("option_e", tmodel.getOptionE());
i.putExtra("answer", tmodel.getOptionAnswer());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
});
recyclerView.post(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
View viewTemp = recyclerView.getLayoutManager().findViewByPosition(i);
CardView cardView = (CardView) viewTemp.findViewById(R.id.cardView);
//TO DO
}
}

});

* 如果适配器保持相同的大小(未被添加项或删除更改) ,可以在适配器中创建一个 ViewHolder 列表,然后在 onCreateViewHolder 中将新的 ViewHolder 添加到列表中。在哪里可以访问适配器,您可以通过列表访问 ViewHolder 到特定的位置: Adapter.listHolder.get (position)

* 对于不相等大小的适配器: 小咬复杂,更新列表保持器的新项目添加到保持器,或删除