Bagaimana cara membangun Horizontal ListView dengan RecyclerView?

338

Saya perlu menerapkan tampilan daftar horizontal dalam aplikasi Android saya. Saya melakukan sedikit riset dan menemukan Bagaimana saya bisa membuat ListView horizontal di Android? dan Horizontal ListView di Android? Namun, pertanyaan-pertanyaan ini diajukan sebelum Recyclerview dirilis. Apakah ada cara yang lebih baik untuk mengimplementasikan ini sekarang dengan Recyclerview?

Andre Perkins
sumber
12
Cukup gunakan LinearLayoutManagerdengan orientasi yang diatur ke HORIZONTAL.
Egor Neliuba
@EgorN saya mencobanya, itu membuatnya horizontal tetapi tampaknya itu bahkan mengubah anak-anak dari baris adaptor ke horizontal juga. saya punya RelativeLayout. saya tidak yakin bagaimana cara memperbaikinya?
Muhammad Umar

Jawaban:

740

Apakah ada cara yang lebih baik untuk mengimplementasikan ini sekarang dengan Recyclerview sekarang?

Iya.

Saat Anda menggunakan RecyclerView, Anda harus menentukan LayoutManageryang bertanggung jawab untuk meletakkan setiap item dalam tampilan. The LinearLayoutManagermemungkinkan Anda untuk menentukan orientasi, seperti biasa LinearLayoutakan.

Untuk membuat daftar horizontal RecyclerView, Anda dapat melakukan sesuatu seperti ini:

LinearLayoutManager layoutManager
    = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
Bryan Herbst
sumber
saya mencoba itu, itu membuatnya horisontal tetapi tampaknya bahkan mengubah anak-anak dari baris adaptor ke horizontal juga. saya punya RelativeLayout. saya tidak yakin bagaimana cara memperbaikinya?
Muhammad Umar
2
RelativeLayouttidak memiliki konsep horizontal vs vertikal, jadi saya tidak begitu mengerti pertanyaannya.
Bryan Herbst
2
Rupanya ada beberapa masalah dengan RecyclerView dan LayoutManager yang bergulir secara horizontal ... code.google.com/p/android/issues/detail?id=74772 - menemukannya karena saya kesulitan juga dengan benar-benar menggunakan RecyclerView yang bergulir secara horizontal
AgentKnopf
Zainodis sudahkah Anda tahu apa yang harus digunakan? LinearLayoutManager bahkan tidak muncul sebagai impor untuk saya? Apakah saya kehilangan sesuatu
Lion789
@ Tanis.7x Ini sangat bagus untuk saya, tetapi mengisi daftar dari kiri ke kanan. Adakah yang tahu jika ada cara untuk mengisi dari kanan ke kiri? (Item pertama paling benar dalam daftar, item di indeks 1 kemudian ke kiri, dan seterusnya ...)
mengangkat
169
 <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" />
air mendidih
sumber
bagaimana cara mengatur LayoutManager?
Kai Wang
@ Kaiwang, mohon lihat jawaban "Tanis.7x" di atas.
rebus
app:layoutManager="android.support.v7.widget.LinearLayoutManager"tidak akan berfungsi untuk rilis build. Saya telah menghadapi masalah ini Rilis build.
Abu Yousuf
Saya mencari cara untuk menunjukkan ini di pembangun antarmuka. alat: orientasi = "horisontal" alat: layoutManager = "android.support.v7.widget.LinearLayoutManager" menyelamatkan saya terima kasih.
Mohammad Tabbara
Android /> '
Yanny
74

Contoh lengkap

masukkan deskripsi gambar di sini

Satu-satunya perbedaan nyata antara vertikal RecyclerViewdan horizontal adalah bagaimana Anda mengatur LinearLayoutManager. Berikut ini cuplikan kode. Contoh lengkapnya di bawah ini.

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

Contoh yang lebih lengkap ini dimodelkan setelah jawaban vertikal sayaRecyclerView .

Perbarui dependensi Gradle

Pastikan dependensi berikut ada di gradle.buildfile aplikasi Anda :

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

Anda dapat memperbarui nomor versi ke apa pun yang terbaru .

Buat tata letak aktivitas

Tambahkan RecyclerViewtata letak ke xml Anda.

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>

Buat tata letak item

Setiap item di kami RecyclerViewakan memiliki satu warna di Viewatas TextView. Buat file sumber daya tata letak baru.

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>

Buat adaptor

The RecyclerViewperlu adaptor untuk mengisi pandangan di setiap baris (item horisontal) dengan data Anda. Buat file java baru.

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);
    }
}

Catatan

  • Meskipun tidak sepenuhnya diperlukan, saya menyertakan fungsionalitas untuk mendengarkan acara klik pada item. Ini tersedia di yang lama ListViewsdan merupakan kebutuhan bersama. Anda dapat menghapus kode ini jika Anda tidak membutuhkannya.

Inisialisasi RecyclerView dalam Aktivitas

Tambahkan kode berikut ke aktivitas utama Anda.

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();
    }
}

Catatan

  • Perhatikan bahwa aktivitas mengimplementasikan apa ItemClickListeneryang kami tetapkan dalam adaptor kami. Ini memungkinkan kami untuk menangani acara klik item di onItemClick.

Jadi

Itu dia. Anda harus dapat menjalankan proyek Anda sekarang dan mendapatkan sesuatu yang mirip dengan gambar di atas.

Catatan

Suragch
sumber
12

Jika Anda ingin menggunakan RecyclerViewdengan GridLayoutManager, ini adalah cara untuk mencapai gulir horizontal.

recyclerView.setLayoutManager(
new GridLayoutManager(recyclerView.getContext(), rows, GridLayoutManager.HORIZONTAL, false));
José Cabrera
sumber
Ini bekerja dengan baik untuk saya ... terutama karena Anda dapat mengatur baris num ... kemungkinan untuk melakukan ini juga di LinearLayoutManager?
superUser
9

Mencoba membuat ListView horizontal terlalu banyak waktu. Saya telah menyelesaikannya dengan dua cara.

1. Dengan menggunakan ViewPager yang adaptornya memanjang dari PagerAdapter.

2. Dengan menggunakan RecyclerView seperti di atas. Perlu menerapkan LayoutManager seperti pada kode berikut:

LinearLayoutManager layoutManager
    = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
Jayman Jani
sumber
6

Jika Anda ingin menggunakan Horizontal Recycler View untuk bertindak sebagai ViewPager maka mungkin sekarang dengan bantuan LinearSnapHelperyang ditambahkan di Perpustakaan Dukungan versi 24.2.0.

Pertama Tambahkan RecyclerView ke Aktivitas / Fragmen Anda

<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>

Dalam kasus saya, saya telah menggunakan CardViewdi dalamRecyclerView

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>

Dalam Aktivitas / Fragmen Anda

    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);

Langkah terakhir adalah mengatur adaptor ke RecyclerView

mBlogList.setAdapter(firebaseRecyclerAdapter);
AndroidBeginner
sumber
4

Dengan rilis perpustakaan RecyclerView, sekarang Anda dapat menyelaraskan daftar gambar yang diikat dengan teks dengan mudah. Anda dapat menggunakan LinearLayoutManager untuk menentukan arah di mana Anda ingin mengarahkan daftar Anda, baik vertikal atau horizontal seperti yang ditunjukkan di bawah ini.

masukkan deskripsi gambar di sini

Anda dapat mengunduh demo yang berfungsi penuh dari pos ini

Daniel Nyamasyo
sumber
2
 <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:scrollbars="vertical|horizontal" />
        </HorizontalScrollView>

    import androidx.appcompat.app.AppCompatActivity;
    import android.content.Context;
    import android.content.ContextWrapper;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.Toast;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    public class MainActivity extends AppCompatActivity
     {
        ImageView mImageView1;
        Bitmap bitmap;
        String mSavedInfo;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mImageView1 = (ImageView) findViewById(R.id.image);
        }
        public Bitmap getBitmapFromURL(String src) {
            try {
                java.net.URL url = new java.net.URL(src);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap myBitmap = BitmapFactory.decodeStream(input);
                return myBitmap;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
        public void button2(View view) {
            new DownloadImageFromTherad().execute();
        }
        private class DownloadImageFromTherad extends AsyncTask<String, Integer, String> {
            @Override
            protected String doInBackground(String... params) {
                bitmap = getBitmapFromURL("https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png");
                return null;
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                File sdCardDirectory = Environment.getExternalStorageDirectory();
                File image = new File(sdCardDirectory, "test.png");
                boolean success = false;
                FileOutputStream outStream;
                mSavedInfo = saveToInternalStorage(bitmap);
                if (success) {
                    Toast.makeText(getApplicationContext(), "Image saved with success", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Error during image saving" + mSavedInfo, Toast.LENGTH_LONG).show();
                }
            }
        }
        private String saveToInternalStorage(Bitmap bitmapImage) {
            ContextWrapper cw = new ContextWrapper(getApplicationContext());
            // path to /data/data/yourapp/app_data/imageDir
            File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
            File mypath = new File(directory, "profile.jpg");
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(mypath);
                bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return directory.getAbsolutePath();
        }
        private void loadImageFromStorage(String path) {
            try {
                File f = new File(path, "profile.jpg");
                Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
                mImageView1.setImageBitmap(b);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        public void showImage(View view) {
            loadImageFromStorage(mSavedInfo);
        }
    }
Syed Danish Haider
sumber
1

Ada subkelas RecyclerView bernama HorizontalGridView Anda dapat menggunakannya untuk memiliki arah horisontal. VerticalGridView untuk arah vertikal

Andrew Luca
sumber
5
Apakah HorizontalGridView bahkan dimaksudkan untuk digunakan untuk perangkat non-TV? Afaik perpustakaan leanback dimaksudkan untuk TV
AgentKnopf
2
menggunakan leanback akan meningkatkan minSdkVersion aplikasi Anda menjadi 17
Seseorang di Suatu Tempat
1

Ini untuk Horizontal dan Vertical.

RecyclerView recyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_recycler);
    recyclerView = (RecyclerView)findViewById(R.id.recyclerViewId);

    RecyclAdapter adapter = new RecyclAdapter();

    //Vertical RecyclerView
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);

    //Horizontal RecyclerView
    //recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.HORIZONTAL,false));

    recyclerView.setAdapter(adapter);

}
Akbar Khan
sumber
1

Tampilan Pendaur Ulang dalam Horizontal Dynamic.

Implementasi Tampilan Pendaur Ulang

RecyclerView musicList = findViewById(R.id.MusicList);

// RecyclerView musiclist = findViewById(R.id.MusicList1);
// RecyclerView musicLIST = findViewById(R.id.MusicList2);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
musicList.setLayoutManager(layoutManager);

String[] names = {"RAP", "CH SHB", "Faheem", "Anum", "Shoaib", "Laiba", "Zoki", "Komal", "Sultan","Mansoob Gull"};
musicList.setAdapter(new ProgrammingAdapter(names));'

Kelas adaptor untuk tampilan pendaur ulang, di mana ada penahan pandangan untuk menahan pandangan pendaur ulang itu

public class ProgrammingAdapter 
     extendsRecyclerView.Adapter<ProgrammingAdapter.programmingViewHolder> {

private String[] data;

public ProgrammingAdapter(String[] data)
{
    this.data = data;
}

@Override
public programmingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.list_item_layout, parent, false);

    return new programmingViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull programmingViewHolder holder, int position) {
    String title = data[position];
    holder.textV.setText(title);
}

@Override
public int getItemCount() {
    return data.length;
}

public class programmingViewHolder extends RecyclerView.ViewHolder{
    ImageView img;
    TextView textV;
    public programmingViewHolder(View itemView) {
        super(itemView);
        img =  itemView.findViewById(R.id.img);
        textV =  itemView.findViewById(R.id.textt);
    }
}
Faheem Khan
sumber
1
recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));

recyclerView.setAdapter(adapter);
Hamza Ali
sumber
0

Coba ini:

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

hanya jika Anda punya tampilan pendaur ulang dengan beberapa fragmen di atasnya.

John Vergara
sumber