首页 文章

如何使用RecyclerView构建Horizontal ListView?

提问于
浏览
249

我需要在我的Android应用程序中实现水平列表视图 . 我做了一些研究并遇到了How can I make a horizontal ListView in Android?Horizontal ListView in Android?但是,在Recyclerview发布之前就提出了这些问题 . 现在使用Recyclerview有更好的方法来实现吗?

9 回答

  • 0
    <android.support.v7.widget.RecyclerView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
    
  • 11

    完整的例子

    enter image description here

    垂直 RecyclerView 和水平的唯一真正区别在于如何设置 LinearLayoutManager . 这是代码片段 . 完整的例子如下 .

    LinearLayoutManager horizontalLayoutManagaer = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(horizontalLayoutManagaer);
    

    这个更完整的例子是在my vertical RecyclerView answer之后建模的 .

    更新Gradle依赖项

    确保您的app gradle.build 文件中包含以下依赖项:

    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    

    您可以将版本号更新为the most current .

    创建活动布局

    RecyclerView 添加到xml布局中 .

    activity_main.xml中

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

    创建项目布局

    我们 RecyclerView 中的每个项目都会在 TextView 上有一个彩色的 View . 创建一个新的布局资源文件 .

    recyclerview_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp">
    
        <View
            android:id="@+id/colorView"
            android:layout_width="100dp"
            android:layout_height="100dp"/>
    
        <TextView
            android:id="@+id/tvAnimalName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"/>
    
    </LinearLayout>
    

    创建适配器

    RecyclerView 需要一个适配器来填充每行(水平项)中的视图和您的数据 . 创建一个新的java文件 .

    MyRecyclerViewAdapter.java

    public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
    
        private List<Integer> mViewColors;
        private List<String> mAnimals;
        private LayoutInflater mInflater;
        private ItemClickListener mClickListener;
    
        // data is passed into the constructor
        MyRecyclerViewAdapter(Context context, List<Integer> colors, List<String> animals) {
            this.mInflater = LayoutInflater.from(context);
            this.mViewColors = colors;
            this.mAnimals = animals;
        }
    
        // inflates the row layout from xml when needed
        @Override
        @NonNull
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
            return new ViewHolder(view);
        }
    
        // binds the data to the view and textview in each row
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            int color = mViewColors.get(position);
            String animal = mAnimals.get(position);
            holder.myView.setBackgroundColor(color);
            holder.myTextView.setText(animal);
        }
    
        // total number of rows
        @Override
        public int getItemCount() {
            return mAnimals.size();
        }
    
        // stores and recycles views as they are scrolled off screen
        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
            View myView;
            TextView myTextView;
    
            ViewHolder(View itemView) {
                super(itemView);
                myView = itemView.findViewById(R.id.colorView);
                myTextView = itemView.findViewById(R.id.tvAnimalName);
                itemView.setOnClickListener(this);
            }
    
            @Override
            public void onClick(View view) {
                if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
            }
        }
    
        // convenience method for getting data at click position
        public String getItem(int id) {
            return mAnimals.get(id);
        }
    
        // allows clicks events to be caught
        public void setClickListener(ItemClickListener itemClickListener) {
            this.mClickListener = itemClickListener;
        }
    
        // parent activity will implement this method to respond to click events
        public interface ItemClickListener {
            void onItemClick(View view, int position);
        }
    }
    

    笔记

    • 虽然不是绝对必要,但我还包含了监听项目点击事件的功能 . 这在旧的 ListViews 中可用,并且是常见的需求 . 如果您不需要,可以删除此代码 .

    在活动中初始化RecyclerView

    将以下代码添加到主活动中 .

    MainActivity.java

    public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
    
        private MyRecyclerViewAdapter adapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // data to populate the RecyclerView with
            ArrayList<Integer> viewColors = new ArrayList<>();
            viewColors.add(Color.BLUE);
            viewColors.add(Color.YELLOW);
            viewColors.add(Color.MAGENTA);
            viewColors.add(Color.RED);
            viewColors.add(Color.BLACK);
    
            ArrayList<String> animalNames = new ArrayList<>();
            animalNames.add("Horse");
            animalNames.add("Cow");
            animalNames.add("Camel");
            animalNames.add("Sheep");
            animalNames.add("Goat");
    
            // set up the RecyclerView
            RecyclerView recyclerView = findViewById(R.id.rvAnimals);
            LinearLayoutManager horizontalLayoutManager
                    = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
            recyclerView.setLayoutManager(horizontalLayoutManager);
            adapter = new MyRecyclerViewAdapter(this, viewColors, animalNames);
            adapter.setClickListener(this);
            recyclerView.setAdapter(adapter);
        }
    
        @Override
        public void onItemClick(View view, int position) {
            Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on item position " + position, Toast.LENGTH_SHORT).show();
        }
    }
    

    笔记

    • 请注意,该活动实现了我们在适配器中定义的 ItemClickListener . 这允许我们处理 onItemClick 中的项目点击事件 .

    完了

    而已 . 您现在应该能够运行项目并获得与顶部图像类似的内容 .

    注意事项

  • 48

    如果要将 RecyclerViewGridLayoutManager 一起使用,这是实现水平滚动的方法 .

    recyclerView.setLayoutManager(
    new GridLayoutManager(recyclerView.getContext(), rows, GridLayoutManager.HORIZONTAL, false));
    
  • 561

    现在使用Recyclerview有更好的方法来实现吗?

    是 .

    使用 RecyclerView 时,需要指定 LayoutManager ,负责在视图中布置每个项目 . LinearLayoutManager允许您指定方向,就像普通的 LinearLayout 一样 .

    要使用 RecyclerView 创建水平列表,您可能会执行以下操作:

    LinearLayoutManager layoutManager
        = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    
    RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
    myList.setLayoutManager(layoutManager);
    
  • 1

    尝试构建水平ListView需要花费太多时间 . 我已经用两种方式解决了这个问题 .

    1.使用ViewPager,其适配器从PagerAdapter扩展 .

    2.如上所述使用RecyclerView . 需要应用LayoutManager,如下面的代码所示:

    LinearLayoutManager layoutManager
        = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    
    RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
    myList.setLayoutManager(layoutManager);
    
  • 129

    如果您希望使用Horizontal Recycler View作为ViewPager,那么现在可以在支持库版本24.2.0中添加 LinearSnapHelper 的帮助下使用 .

    Firstly Add RecyclerView to your Activity/Fragment

    <android.support.v7.widget.RecyclerView
            android:layout_below="@+id/sign_in_button"
            android:layout_width="match_parent"
            android:orientation="horizontal"
            android:id="@+id/blog_list"
            android:layout_height="match_parent">
        </android.support.v7.widget.RecyclerView>
    

    在我的情况下,我在 RecyclerView 内使用了 CardView

    blog_row.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView 
    
        xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_margin="15dp"
            android:orientation="vertical">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:orientation="vertical">
    
                <com.android.volley.toolbox.NetworkImageView
                    android:id="@+id/imageBlogPost"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:adjustViewBounds="true"
                    android:paddingBottom="15dp"
                    android:src="@drawable/common_google_signin_btn_text_light_normal" />
    
                <TextView
                    android:id="@+id/TitleTextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                   android:layout_marginBottom="20dp"
    
                    android:text="Post Title Here"
                    android:textSize="16sp" />
    
                <TextView
                    android:id="@+id/descriptionTextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Post Description Here"
                    android:paddingBottom="15dp"
                    android:textSize="14sp" />
            </LinearLayout>
    
        </android.support.v7.widget.CardView>
    

    In your Activity/Fragment

    private RecyclerView mBlogList;
    
    
    
    
     LinearLayoutManager layoutManager
                        = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
                mBlogList = (RecyclerView) findViewById(R.id.blog_list);
    
                mBlogList.setHasFixedSize(true);
                mBlogList.setLayoutManager(layoutManager);
    
    LinearSnapHelper snapHelper = new LinearSnapHelper() {
                @Override
                public int findTargetSnapPosition(RecyclerView.LayoutManager lm, int velocityX, int velocityY) {
                    View centerView = findSnapView(lm);
                    if (centerView == null)
                        return RecyclerView.NO_POSITION;
    
                    int position = lm.getPosition(centerView);
                    int targetPosition = -1;
                    if (lm.canScrollHorizontally()) {
                        if (velocityX < 0) {
                            targetPosition = position - 1;
                        } else {
                            targetPosition = position + 1;
                        }
                    }
    
                    if (lm.canScrollVertically()) {
                        if (velocityY < 0) {
                            targetPosition = position - 1;
                        } else {
                            targetPosition = position + 1;
                        }
                    }
    
                    final int firstItem = 0;
                    final int lastItem = lm.getItemCount() - 1;
                    targetPosition = Math.min(lastItem, Math.max(targetPosition, firstItem));
                    return targetPosition;
                }
            };
            snapHelper.attachToRecyclerView(mBlogList);
    

    Last Step is to set adapter to RecyclerView

    mBlogList.setAdapter(firebaseRecyclerAdapter);
    
  • 4

    随着RecyclerView库的发布,现在您可以轻松地将图像列表与文本对齐 . 您可以使用LinearLayoutManager指定列表方向,垂直或水平,如下所示 .

    enter image description here

    You can download a full working demo from this post

  • 6

    有一个名为HorizontalGridView的RecyclerView子类,您可以使用它来获得水平方向 . VerticalGridView表示垂直方向

  • 9

    试试这个:

    myrecyclerview.setLayoutManager(
            new LinearLayoutManager(getActivity(),
                                    LinearLayoutManager.HORIZONTAL,false));
    myrecyclerview.setAdapter(recyclerAdapter);
    

    只有在你有一个带有一些碎片的回收者视图的情况下 .

相关问题