How do I layout nested RecyclerViews, while remaining performant?

前端 未结 2 545
再見小時候
再見小時候 2020-12-02 15:37

I am trying to achieve something similar to Google Play Music\'s \"Listen Now\" layout. Every example I have found on the web is a single, simple RecyclerView.

相关标签:
2条回答
  • 2020-12-02 16:17

    You can't take recyclerview inside recyclerview tag. Rather in your first adapter's bindViewHolder call again recyclerview adapter like:-

    InnerRecyclerviewAdapter adapter=new InnerRecyclerviewAdapter(context,urlistArray);
    holder.recyclerView.setAdapter(adapter);
    holder.recyclerView.setHasFixedSize(true);
    LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(layoutManager);
    

    wrap_content will also work with latest recyclerview

    for more info check out this link https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView

    0 讨论(0)
  • 2020-12-02 16:20

    I have tried to solve the case where you have a horizontal RecyclerView within the vertical RecyclerView and this is my code.

    SingleFragmentActivity

    package com.example.uitestingmaterialdesign;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v7.app.AppCompatActivity;
    
    
    public abstract class SingleFragmentActivity extends AppCompatActivity {
    
    protected abstract Fragment createFragment();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_fragment_activity);
    
        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.simple_fragment_container);
    
        if (fragment == null) {
            fragment = createFragment();
            fm.beginTransaction()
                    .add(R.id.simple_fragment_container, fragment)
                    .commit();
        }
    }
    
    }
    

    MainActivity

    package com.example.uitestingmaterialdesign;
    
    import android.support.v4.app.Fragment;
    
    public class MainActivity extends SingleFragmentActivity {
    
    @Override
    protected Fragment createFragment() {
        return new PrimaryRecyclerViewFragment();
    }
    
    }
    

    PrimaryRecyclerView

    package com.example.uitestingmaterialdesign;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    
    public class PrimaryRecyclerViewFragment extends Fragment {
    
    private RecyclerView mPrimaryRecyclerView;
    private String[] mMoviesGenre, mActionMovies;
    
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        mMoviesGenre = new String[]{
                "Action", "Adventure", "Comedy", "Crime", "Fantasy",
                "Historical", "Horror", "Magical", "Mystery", "Paranoid"
        };
    
        mActionMovies = new String[] {"Mission: Impossible – Rogue Nation", 
                "Mad Max: Fury Road", "Star Wars: The Force Awakens",
                "Avengers: Age of Ultron", "Ant- Man","Terminator Genisys",        "Furious 7",              "Blackhat", "The Man from U.N.C.L.E",
                "Jurassic World"
        };
    
    }
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.primary_recycler_view, container, false);
    
        // Creating the primary recycler view adapter
        PrimaryAdapter adapter = new PrimaryAdapter(mMoviesGenre);
    
        LinearLayoutManager layoutManager = new LinearLayoutManager(
                getActivity(),
                LinearLayoutManager.VERTICAL,
                false
        );
    
        mPrimaryRecyclerView = (RecyclerView) view.findViewById(R.id.primary_recycler_view);
        mPrimaryRecyclerView.setLayoutManager(layoutManager);
        mPrimaryRecyclerView.setAdapter(adapter);
    
        return view;
    }
    
    private class PrimaryViewHolder extends RecyclerView.ViewHolder {
        private TextView mPrimaryMovieGenre;
        private RecyclerView mSecondaryRecyclerView;
    
        public PrimaryViewHolder(View itemView) {
            super(itemView);
            mPrimaryMovieGenre = (TextView) itemView.findViewById(R.id.primary_movie_genre);
            mSecondaryRecyclerView = (RecyclerView) itemView.findViewById(R.id.secondary_recycler_view);
        }
    
        // This get called in PrimaryAdapter onBindViewHolder method
        public void bindViews(String genre, int position) {
            mPrimaryMovieGenre.setText(genre);
    
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                    getActivity(),
                    LinearLayoutManager.HORIZONTAL,
                    false
            );
    
            mSecondaryRecyclerView.setLayoutManager(linearLayoutManager);
            mSecondaryRecyclerView.setAdapter(getSecondaryAdapter(position));
        }
    }
    
    private class PrimaryAdapter extends RecyclerView.Adapter<PrimaryViewHolder> {
        private String[] mMovieGenre;
    
        public PrimaryAdapter(String[] moviesGenre) {
            mMovieGenre = moviesGenre;
        }
    
        @Override
        public PrimaryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            View view = inflater.inflate(R.layout.primary_recycler_view_item, parent, false);
            return new PrimaryViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(PrimaryViewHolder holder, int position) {
            String genre = mMovieGenre[position];
            holder.bindViews(genre, position);
        }
    
        @Override
        public int getItemCount() {
            return mMovieGenre.length;
        }
    }
    
    private class SecondaryViewHolder extends RecyclerView.ViewHolder {
    
        private TextView mTextView;
    
        public SecondaryViewHolder(View view) {
            super(view);
            mTextView = (TextView) itemView.findViewById(R.id.secondary_text_view);
        }
    
        public void bindView(String name) {
            mTextView.setText(name);
        }
    }
    
    private class SecondaryAdapter extends RecyclerView.Adapter<SecondaryViewHolder> {
        private String[] mMovies;
    
        public SecondaryAdapter(String[] movies) {
            mMovies = movies;
        }
    
        @Override
        public SecondaryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            View view = inflater.inflate(R.layout.secondary_recycler_view_item, parent, false);
            return new SecondaryViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(SecondaryViewHolder holder, int position) {
            String name = mMovies[position];
            holder.bindView(name);
        }
    
        @Override
        public int getItemCount() {
            return mMovies.length;
        }
    }
    
    private SecondaryAdapter getSecondaryAdapter(int position) {
    
        SecondaryAdapter adapter;
        switch (position) {
            case 0:
                return new SecondaryAdapter(mActionMovies);
            case 1:
                return null;
            case 2:
                return null;
            case 3:
                return null;
            case 4:
                return null;
            case 5:
                return null;
            case 6:
                return null;
            case 7:
                return null;
            case 8:
                return null;
            case 9:
                return null;
            default:
                return null;
        }
    }
    }
    

    Primary_recycler_view.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/primary_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
    

    primary_recycler_view_item.xml (with a horizontal recycler view)

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">
    
    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="2dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="8dp"
            android:layout_gravity="bottom">
    
            <TextView
                android:id="@+id/primary_movie_genre"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="20sp"
                android:paddingTop="16dp"
                android:paddingBottom="16dp"/>
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/secondary_recycler_view"
                android:layout_gravity="center_horizontal"
                android:layout_width="360dp"
                android:layout_height="180dp"/>
        </LinearLayout>
    
    </android.support.v7.widget.CardView>
    
    </LinearLayout>
    

    secondary_recycler_view_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="8dp"
    android:gravity="center">
    
    <TextView
        android:id="@+id/secondary_text_view"
        android:layout_width="120dp"
        android:layout_height="160dp"
        android:gravity="center|bottom"
        android:background="#BDBDBD"/>
    </LinearLayout>
    

    single_fragment_activity

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/simple_fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
    

    If you have any question or you have found a better way of doing it, please let know and I hope this helps.

    0 讨论(0)
提交回复
热议问题