Je dois implémenter une listview horizontale dans mon application Android. J'ai fait un peu de recherche et suis tombé sur Comment puis-je créer un ListView horizontal sous Android? et Liste horizontale dans Android? cependant, ces questions ont été posées avant la publication de Recyclerview. Existe-t-il un meilleur moyen de mettre cela en œuvre maintenant avec Recyclerview?
Existe-t-il un meilleur moyen de mettre cela en œuvre maintenant avec Recyclerview maintenant?
Oui.
Lorsque vous utilisez une RecyclerView
, vous devez spécifier une LayoutManager
responsable de la disposition de chaque élément de la vue. Le LinearLayoutManager
vous permet de spécifier une orientation, exactement comme le ferait une LinearLayout
normale.
Pour créer une liste horizontale avec RecyclerView
, vous pouvez faire quelque chose comme ceci:
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
<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" />
La seule différence réelle entre un RecyclerView
vertical et un horizontal est la manière dont vous configurez le LinearLayoutManager
. Voici l'extrait de code. L'exemple complet est ci-dessous.
LinearLayoutManager horizontalLayoutManagaer = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(horizontalLayoutManagaer);
Cet exemple plus complet est modélisé d'après ma réponse RecyclerView
verticale .
Assurez-vous que les dépendances suivantes figurent dans votre fichier app gradle.build
:
implementation 'com.Android.support:appcompat-v7:27.1.1'
implementation 'com.Android.support:recyclerview-v7:27.1.1'
Vous pouvez mettre à jour les numéros de version vers tout ce qui est le plus récent .
Ajoutez le RecyclerView
à votre mise en page 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>
Chaque article de notre RecyclerView
aura un seul View
de couleur sur un TextView
. Créez un nouveau fichier de ressources de présentation.
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
a besoin d'un adaptateur pour remplir les vues de chaque ligne (élément horizontal) avec vos données. Créez un nouveau fichier 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);
}
}
Remarques
ListViews
et est un besoin commun. Vous pouvez supprimer ce code si vous n'en avez pas besoin.Ajoutez le code suivant à votre activité principale.
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();
}
}
Remarques
ItemClickListener
que nous avons défini dans notre adaptateur. Cela nous permet de gérer les événements de clic d’élément dans onItemClick
.C'est tout. Vous devriez être capable de lancer votre projet maintenant et d’obtenir quelque chose de similaire à l’image en haut.
Si vous voulez utiliser une RecyclerView
avec la GridLayoutManager
, c'est le moyen de réaliser le défilement horizontal.
recyclerView.setLayoutManager(
new GridLayoutManager(recyclerView.getContext(), rows, GridLayoutManager.HORIZONTAL, false));
Essayer de construire un ListView horizontal prend trop de temps. Je l'ai résolu de deux manières.
1.En utilisant un ViewPager dont l'adaptateur s'étend depuis PagerAdapter.
2.En utilisant RecyclerView comme ci-dessus. Besoin d'appliquer LayoutManager comme dans le code suivant:
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);
Si vous souhaitez utiliser la vue horizontale du recycleur pour agir en tant que ViewPager, vous pouvez le faire à l’aide de LinearSnapHelper
, ajouté à la bibliothèque de support 24.2.0.
Tout d’abord, ajoutez RecyclerView à votre activité/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>
Dans mon cas, j'ai utilisé une CardView
à l'intérieur de la RecyclerView
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>
Dans votre activité/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);
La dernière étape consiste à configurer l'adaptateur sur RecyclerView
mBlogList.setAdapter(firebaseRecyclerAdapter);
Avec la sortie de la bibliothèque RecyclerView, vous pouvez désormais aligner facilement une liste d’images reliées au texte. Vous pouvez utiliser LinearLayoutManager pour spécifier la direction dans laquelle vous souhaitez orienter votre liste, verticale ou horizontale, comme indiqué ci-dessous.
Vous pouvez télécharger une démo complète active à partir de cet article
Il existe une sous-classe RecyclerView nommée HorizontalGridView vous pouvez l’utiliser pour une direction horizontale . VerticalGridView pour une direction verticale
Recycler Voir en dynamique horizontale.
Mise en œuvre de la vue Recycler
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));'
Classe d'adaptateur pour la vue du recycleur, dans laquelle se trouve un détenteur de vue pour maintenir la vue de ce recycleur
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);
}
}
C'est à la fois pour Horizontal et pour 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);
}
Essaye ça:
myrecyclerview.setLayoutManager(
new LinearLayoutManager(getActivity(),
LinearLayoutManager.HORIZONTAL,false));
myrecyclerview.setAdapter(recyclerAdapter);
seulement dans le cas où vous avez une vue recycleur avec des fragments dessus.
<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>