私はRecyclerView
とImageView
で活動しています。画像のリストを水平に表示するためにRecyclerView
を使用しています。 RecyclerView
の画像をクリックすると、アクティビティのImageView
は画像のより大きな画像を表示するはずです。これまでのところ、すべてうまくいきます。
現在、アクティビティにはさらに2つのImageButtons
があります:imageButton_left
とimageButton_right
。 imageButton_left
をクリックすると、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
というNiceメソッドを持っています
指定されたアダプタ位置を表すビューを見つけます。
あなたが必要とするのはあなたが興味がある項目のアダプターの位置だけです。
edit:コメントのPaul Woitaschekが指摘しているように、findViewByPosition
はLayoutManager
のメソッドであるため、すべてのLayoutManagerで機能します(つまりStaggeredGridLayoutManager
、等。)
これがあなたが探しているものです。
私もこの問題を抱えていました。そしてあなたと同じように、答えは見つけるのがとても難しいです。しかし、そこに IS ViewHolderを特定の位置から取得するための簡単な方法があります(おそらく、アダプタで多くのことをするでしょう)。
myRecyclerView.findViewHolderForAdapterPosition(pos);
注:ビューがリサイクルされている場合、これはnull
を返します。私の重要な漏れをすぐに見つけてくれたMichaelに感謝します。
View
が必要な場合は、ViewHolderのitemView
プロパティに必ず次のようにアクセスしてください。myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;
両方使用できます
recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition)
とrecyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition)
。 RecyclerViewビューが2種類のポジションを使用していることを確認してください
アダプターの位置:アダプター内のアイテムの位置。これは、アダプターから見た位置です。レイアウト位置:最新のレイアウト計算におけるアイテムの位置。これが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();
}
}
});
}
}
あなたはViewHolderのArrayListを作ることができます:
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);
}
必要に応じて、ArrayListに他のViewHolderを追加または削除します。
次のようにして、リサイクルビュー上の特定のポジションのビューを取得できます。
int position = 2;
RecyclerView.ViewHolder viewHolder = recyclerview.findViewHolderForItemId(position);
View view = viewHolder.itemView;
ImageView imageView = (ImageView)view.findViewById(R.id.imageView);
リサイクラービューの「findViewHolderForAdapterPosition」メソッドを使用するだけで、そこからviewHolderオブジェクトを取得し、そのビューホルダーをアダプタービューホルダーに型キャストして、ビューホルダーのビューに直接アクセスできます。
以下はkotlinのサンプルコードです
val viewHolder = recyclerView.findViewHolderForAdapterPosition(position)
val textview=(viewHolder as YourViewHolder).yourTextView
アダプタがリストに追加されるまで待たなければならないことを覚えておいてください、それからあなたは位置によって見解を得ることを試みることができます
final int i = 0;
recyclerView.setAdapter(adapter);
recyclerView.post(new Runnable() {
@Override
public void run() {
View view = recyclerView.getLayoutManager().findViewByPosition(i);
}
});
これを行うこともできます、これはあなたが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");
}
リサイクラビューリストから特定のビューを取得するにはORリサイクラビューの編集テキストでエラーを表示します。
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 !");
}