티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
RecyclerView - Get view at particular position
RecyclerView - 특정 위치에 있는 뷰 가져오기
문제 내용
I have an activity with a RecyclerView
and an ImageView
. I am using the RecyclerView
to show a list of images horizontally. When I click on an image in the RecyclerView
the ImageView
in the activity should show a bigger picture of the image. So far everything works fine.
저는 RecyclerView와 ImageView가 있는 액티비티를 가지고 있습니다. RecyclerView를 사용하여 이미지 목록을 가로로 표시합니다. RecyclerView에서 이미지를 클릭하면 ImageView에서 해당 이미지의 큰 사진을 표시해야 합니다. 지금까지 모든 것이 잘 작동합니다.
Now there are two more ImageButtons
in the activity: imageButton_left
and imageButton_right
. When I click on imageButton_left
, the image in the ImageView
should turn left and also, the thumbnail in the RecyclerView
should reflect this change. Similar is the case with imageButton_right
.
이제 액티비티에는 RecyclerView와 ImageView가 있습니다. RecyclerView를 사용하여 이미지 목록을 가로로 표시합니다. RecyclerView에서 이미지를 클릭하면 액티비티의 ImageView에 이미지의 큰 사진이 표시됩니다. 지금은 imageButton_left와 imageButton_right라는 두 개의 ImageButtons가 더 있습니다. imageButton_left를 클릭하면 ImageView의 이미지가 왼쪽으로 회전되고, RecyclerView의 썸네일도 이 변경 사항을 반영해야 합니다. imageButton_right의 경우도 마찬가지입니다.
I am able to rotate the ImageView
. But, how can I rotate the thumbnail in the RecyclerView
? How can I get the ViewHolder
's ImageView
?
ImageView를 회전시키는 것은 성공했지만, RecyclerView에서의 썸네일을 어떻게 회전시킬 수 있을까요? ViewHolder의 ImageView를 어떻게 가져올 수 있을까요?
Code:
Activity 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>
My Activity Code:
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);
}
}
My Custom Adapter for RecyclerView:
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());
}
}
}
높은 점수를 받은 Solution
This is what you're looking for.
이게 당신이 찾던 것입니다.
I had this problem too. And like you, the answer is very hard to find. But there IS an easy way to get the ViewHolder from a specific position (something you'll probably do a lot in the Adapter).
저도 이 문제를 겪어봤습니다. 그리고 당신처럼 답변을 찾기가 매우 어려웠습니다. 하지만 Adapter에서 자주 사용하는 특정 위치의 ViewHolder를 쉽게 얻을 수 있는 방법이 있습니다.
myRecyclerView.findViewHolderForAdapterPosition(pos);
NOTE: If the View has been recycled, this will return null
. Thanks to Michael for quickly catching this omission. Furthermore, if the user is scrolling quickly, the view can be recycled even after you obtain this ViewHolder, causing all kinds of problems. So be careful when using this technique, especially if you're doing relatively slow work like changing the look of the View(s).
참고: 만약 View가 리사이클 됐다면, 이 방법은 null을 반환합니다. 빠르게 이 부분을 발견해준 Michael에게 감사드립니다. 또한 사용자가 빠르게 스크롤하는 경우, 이 ViewHolder를 얻은 후에도 View가 재활용될 수 있으며, 이는 뷰의 외형을 변경하는 등의 상대적으로 느린 작업을 수행하는 경우 문제를 일으킬 수 있습니다. 따라서 이 기술을 사용할 때는 특히 이러한 점에 주의해야합니다.
가장 최근 달린 Solution
To get a View from a specific position of recyclerView you need to call findViewHolderForAdapterPosition(position) on recyclerView object that will return RecyclerView.ViewHolder
리사이클러뷰(recyclerView)에서 특정 위치의 뷰를 얻으려면 recyclerView 객체에서 findViewHolderForAdapterPosition(position)을 호출해야 합니다. 이 메서드는 RecyclerView.ViewHolder를 반환합니다.
from the returned RecyclerView.ViewHolder object with itemView you can access all Views at that particular position
반환된 RecyclerView.ViewHolder 객체에서 itemView를 사용하여 해당 위치에 있는 모든 View에 액세스할 수 있습니다.
RecyclerView.ViewHolder rv_view = recyclerView.findViewHolderForAdapterPosition(position);
ImageView iv_wish = rv_view.itemView.findViewById(R.id.iv_item);
출처 : https://stackoverflow.com/questions/33784369/recyclerview-get-view-at-particular-position
'개발 > 안드로이드' 카테고리의 다른 글
'This Handler class should be static or leaks might occur: IncomingHandler' 오류 수정하기 (0) | 2023.02.13 |
---|---|
cordova build android" 명령어 실행 중 "unable to find attribute android:fontVariationSettings and android:ttcIndex" 오류 수정하기 (0) | 2023.02.12 |
안드로이드 ScrollView에서 스크롤 바 트랙 제거하기 (0) | 2023.02.12 |
콘텐트 URI에서 파일 URI 가져오기 (0) | 2023.02.11 |
알림 클릭: 활동이 이미 열려 있습니다 (0) | 2023.02.11 |