У меня есть активность с a RecyclerView
и an ImageView
. Я использую, RecyclerView
чтобы показать список изображений по горизонтали. Когда я нажимаю на изображении в в деятельности должна показать более широкую картину изображения. Пока все работает нормально.RecyclerView
ImageView
Теперь ImageButtons
в активности есть еще два : imageButton_left
и imageButton_right
. Когда я нажимаю на imageButton_left
, изображение ImageView
должно повернуться влево, а также эскиз в нем RecyclerView
должен отражать это изменение. То же самое и с imageButton_right
.
Я могу повернуть ImageView
. Но как я могу повернуть миниатюру в RecyclerView
? Как я могу получить ViewHolder
«S 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());
}
}
}
Ответы:
Я полагаю, вы используете a,
LinearLayoutManager
чтобы показать список. Он имеет метод хороший называемый ,findViewByPosition
чтоВсе, что вам нужно, это положение адаптера интересующего вас элемента.
изменить : как отметил Пол Войташек в комментариях,
findViewByPosition
это метод,LayoutManager
поэтому он будет работать со всеми LayoutManager (т.е.StaggeredGridLayoutManager
и т. д.)источник
LayoutManager
поэтому он будет работать для всех подклассов LayoutManager.Это то, что вы ищете .
У меня тоже была эта пробема. И, как и вам, ответ найти очень сложно. Но ЕСТЬ простой способ получить ViewHolder из определенной позиции (то, что вы, вероятно, много будете делать в адаптере).
myRecyclerView.findViewHolderForAdapterPosition(pos);
ПРИМЕЧАНИЕ. Если представление было переработано, оно вернется
null
. Спасибо Майклу за то, что он быстро уловил мое важное упущение.источник
ViewHolder
вы пытаетесь сослаться, был «переработан», он вернетсяnull
.Если вы хотите
View
, убедитесь, что выitemView
получили доступ к свойству ViewHolder следующим образом:myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;
источник
Вы можете использовать оба
recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition)
иrecyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition)
. Убедитесь, что представление RecyclerView использует два типа позицийПоложение адаптера: Положение элемента в адаптере. Это позиция с точки зрения адаптера. Расположение макета: положение элемента при последнем расчете макета. Это позиция с точки зрения LayoutManager. Вы должны использовать
getAdapterPosition()
дляfindViewHolderForAdapterPosition(adapterPosition)
иgetLayoutPosition()
дляfindViewHolderForLayoutPosition(layoutPosition)
.Возьмите переменную-член, чтобы удерживать ранее выбранную позицию элемента в адаптере recyclerview, и другую переменную-член, чтобы проверить, щелкает ли пользователь в первый раз или нет.
Образец кода и снимки экрана прилагаются для получения дополнительной информации внизу.
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(); } } }); } }
}
источник
Вы можете сделать ArrayList из ViewHolder:
ArrayList<MyViewHolder> myViewHolders = new ArrayList<>(); ArrayList<MyViewHolder> myViewHolders2 = new ArrayList<>();
и все хранят ViewHolder (ы) в списке, например:
@Override public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) { final String str = arrayList.get(position); myViewHolders.add(position,holder); }
и добавьте / удалите другой ViewHolder в ArrayList в соответствии с вашими требованиями.
источник
Вы можете просто использовать метод findViewHolderForAdapterPosition для представления recycler, и вы получите объект viewHolder из него, а затем введите тип этого держателя просмотра в держатель просмотра адаптера, чтобы вы могли напрямую получить доступ к представлениям вашего зрителя.
Ниже приведен пример кода для котлина
источник
Вы можете получить представление для конкретной позиции в recyclerview, используя следующие
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); } });
источник
Чтобы получить представление из определенной позиции recyclerView, вам необходимо вызвать findViewHolderForAdapterPosition (position) для объекта recyclerView, который вернет RecyclerView.ViewHolder
из возвращенного объекта RecyclerView.ViewHolder с помощью itemView вы можете получить доступ ко всем представлениям в этой конкретной позиции
источник
Чтобы получить конкретное представление из списка представлений ресайклера ИЛИ показать ошибку в тексте редактирования представления ресайклера.
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 !"); }
источник
Вы также можете сделать это, это поможет, когда вы захотите изменить представление после нажатия элемента позиции 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"); }
источник
Если вы, ребята, получаете null при каждой попытке получить представление с любой позицией int, попробуйте добавить новый параметр конструктора в свой адаптер, например, так:
class RecyclerViewTableroAdapter( private val fichas: Array<MFicha?>, private val activity: View.OnClickListener, private val indicesGanadores:MutableList<Int> ) : RecyclerView.Adapter<RecyclerViewTableroAdapter.ViewHolder>() { //CODE }
Я добавил indexGanadores, чтобы раскрасить фон моей карты, если моя игра выиграна.
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>())
Удачного кодирования! ...
источник