Трябва да направя нещо като Instagram. Имам хоризонтален RecyclerView за истории и по-долу вертикален RecyclerView за емисии. Искам да постигна същото поведение при превъртане (историите трябва да вървят с емисия при превъртане, а не да остават отгоре, както е фиксирано). Единственото решение, което намерих, е NestedScrollView, но то прави изключително лошо представяне за RecyclerViews, екранът ми замръзва почти завинаги. Опитах много трикове, намерени тук, като nestedScrollEnabled, autoLayoutMeasure и т.н., но нищо не работи. Благодаря.
Хоризонтален и вертикален RecyclerView под един и същ свитък
comment
защо това трябва да реши проблема ми?
- person Ciobanu Razvan   schedule 25.07.2018
comment
Оформлението на координатора е най-добро за поддръжка на множество събития за превъртане. можете да използвате вашето поведение при превъртане cutsom с него
- person Saurabh Bhandari   schedule 25.07.2018
Отговори (2)
Съжалявам, ако това обяснение е твърде абстрактно. Уведомете ме, ако имате нужда да бъда по-ясен.
public class VerticalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static final int TYPE_HEADER = 0;
private static final int TYPE_POST = 1;
List<Post> posts;
List<FeedItems> feedItems; //this array is going to populate the horizontal recycler view. Notice that is passed it on the adapter constructor
public VerticalAdapter(List<Post> posts,List<FeedItems> feedItems) {
this.posts = posts;
this.feedItems = feedItems;
}
public void notifyFeedChanged(List<FeedItems> newFeedItems){
this.feedItems.clear();
this.feedItems = newFeedItems; //set the new feed items in the array
notifyItemChanged(0); //tell the main recycler view "Hey, update your first position". This will cause the onBindViewHolder to be called again an thus, the new items will be set into the horizontal recycler view
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER)
return new HeaderViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.your_header_layout, false));
else if (viewType == TYPE_POST)
return new PostViewHolder (LayoutInflater.from(parent.getContext()).inflate(R.layout.your_post_layout, false));
throw new RuntimeException("Don't know this type");
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof HeaderViewHolder){
//set adapter for the horizontal recycler view
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(((HeaderViewHolder) holder).recyclerView.getContext(),LinearLayoutManager.HORIZONTAL, false)
((HeaderViewHolder) holder).recyclerView.setLayoutManager(linearLayoutManager);
if (((HeaderViewHolder) holder).recyclerView.getAdapter() == null){ //only create the adapter the first time. the following times update the values
AnotherAdaterYouNeedToCreateForTheHorizontalRecyclerView adapter = new AnotherAdaterYouNeedToCreateForTheHorizontalRecyclerView(feedItems);
((HeaderViewHolder) holder).recyclerView.setAdapter(adapter);
}else {
((HeaderViewHolder) holder).recyclerView.getAdapter().notifyDataSetChanged();
}
}else if (holder instanceof PostViewHolder){
//just do the normal post binding
}
}
@Override
public int getItemCount() {
return posts.size() + 1; // +1 because of the header
}
@Override
public int getItemViewType(int position) {
return position == 0 ? TYPE_HEADER : TYPE_POST;
}
private class HeaderViewHolder extends RecyclerView.ViewHolder{
RecyclerView recyclerView;
public HeaderViewHolder(View itemView) {
super(itemView);
recyclerView = itemView.findViewById(R.id.the_recycler_view_id_on_the_heaedr_layout_file);
}
}
private class PostViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
public PostViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.post_image_view_or_whatever);
}
}}
И така, вашият вертикален recyclerview има Post елементите (или каквото и да е вашият пост клас) начертани вертикално, това е лесното нещо за постигане. Сега, за хоризонталния изглед, трябва да внедрите заглавка на recyclerview (вижте моя пример за адаптер). Оформлението на заглавката ще има друг хоризонтален рециклиращ изглед.
person
Tiago Ornelas
schedule
25.07.2018
Добре. Всичко е ясно, с изключение на начина, по който трябва да дефинирам адаптер/мениджър на оформление за хоризонтален recyclerview във вертикалния адаптер. Можете ли да ми предоставите малка мостра с тази част, моля?
- person Ciobanu Razvan; 25.07.2018
Редактирах кода на моите отговори. Моля, имайте предвид, че ще трябва да създадете друг адаптер (в моя пример е AnotherAdaterYouNeedToCreateForTheHorizontalRecyclerView). Този адаптер ще има хоризонталните елементи, които искате да покажете.
- person Tiago Ornelas; 25.07.2018
Добре, разбрах, вече е ясно. Последен въпрос. Как трябва да уведомя хоризонталния адаптер за промени? Мога ли да уведомявам по различен начин промените в емисиите и промените в историите?
- person Ciobanu Razvan; 25.07.2018
Отново редактирах кода. Обърнете внимание на масива feedItems и метода notifyFeedChanged, който добавих
- person Tiago Ornelas; 25.07.2018
А за известия за актуализации на публикации трябва да уведомя адаптера за позиции от 1 до размер на публикации, нали?
- person Ciobanu Razvan; 25.07.2018
Да вярно. Вероятно просто извикайте notifyDataSetChanged на целия адаптер
- person Tiago Ornelas; 26.07.2018
Извикването му за целия адаптер също ще обнови историите, което не е необходимо
- person Ciobanu Razvan; 26.07.2018
Вярно е. Освен ако не внедрите DiffResult (medium.com/@iammert/)
- person Tiago Ornelas; 26.07.2018
Във вашето XML оформление опитайте да запазите изгледа за рециклиране на „заглавка“ и изгледа на рециклиращ инструмент „Публикуване“ във вложен изглед за превъртане. При мен работи.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:text="Welcome"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@color/black_80" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
person
Shivang Ahuja
schedule
16.04.2020