Je veux avoir une vue de grille similaire à celle-ci
Chaque ligne impaire aura deux images de grande taille et les lignes paires auront quatre images plus petites. Comment puis-je y parvenir?
J'ai quelque chose de similaire et j'ai résolu avec le nouveau RecyclerView.
J'ai créé un fragment avec un RecyclerView . RecyclerView sur xml:
<Android.support.v7.widget.RecyclerView xmlns:Android="http://schemas.Android.com/apk/res/Android" xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/filter_subtypes" Android:layout_width="match_parent" Android:layout_height="match_parent" />
Sur votre fragment/activité (OnViewCreated dans mon cas de fragment). Je trouve RecyclerView et définit un adaptateur - une classe d'adaptateur normale hérite de RecyclerView.Adapter <VOTRE classe VIEW HOLDER> - Et puis je crée un GridLayoutManager
final GridLayoutManager mng_layout = new GridLayoutManager(this.getActivity(), TOTAL_CELLS_PER_ROW/*In your case 4*/);
Ensuite, je remplace cette méthode pour définir un nombre dynamique de colonnes (cellules)
mng_layout.setSpanSizeLookup( new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
switch( adapterSubtype.getItemViewType(position) ) {
case FilterSubtypesAdapter.TYPE_LOW:
return TOTAL_CELLS_PER_ROW;
case FilterSubtypesAdapter.TYPE_HIGH:
return 2;
default:
return -1;
}
}
});
myRecyclerView.setLayoutManager(mng_layout);
Avec cela, vous obtiendrez un nombre dynamique de cellules sur vos lignes.
EXTRA: Si vous utilisez la même vue vue/type sur votre adaptateur, vous obtiendrez la même vue w & h. Vous devrez créer 2 vues xml pour TYPE_HIGH et une autre vue pour TYPE_LOW.
Ainsi, dans votre adaptateur, vous devez disposer de 2 types de données (1 pour les images hautes et 1 pour les images basses). Vous devez remplacer ces méthodes
@Override
public SubtypeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
if (viewType==TYPE_HIGH) {
view = inflater.inflate(R.layout.item_image_high, parent, false);
} else {
view = inflater.inflate(R.layout.item_image_low, parent, false);
}
return new SubtypeViewHolder(view, viewType);
}
@Override
public int getItemViewType(int position) {
return (list.get(position).getType()==Subtype_type.HIGH) ? TYPE_HIGH : TYPE_LOW;
}
J'espère que j'ai été clair, tout problème me le dit.
Au lieu de considérer une seule image, je prends un groupe de trois images comme un seul élément de grille,
essayez ceci à l'intérieur de votre adaptateur de réseau
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/linear"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/green"
Android:orientation="vertical">
<ImageView
Android:id="@+id/image"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:scaleType="fitXY"
Android:src="@drawable/user"
/>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<ImageView
Android:id="@+id/image_1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:scaleType="fitXY"
Android:src="@drawable/user"
/>
<ImageView
Android:id="@+id/image_2"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:src="@drawable/user"
Android:scaleType="fitXY"
Android:layout_weight="1"
/>
</LinearLayout>
</LinearLayout>
et votre vue de grille serait comme
<GridView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/RelativeLayout1"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:numColumns="2"
>
</GridView>
La seule chose dont vous devez vous occuper est la séquence de votre image. cela pourrait vous aider
Si vous utilisez RecyclerView
pour GridView
, alors il existe une solution qui devrait fonctionner pour vous:
GridLayoutManager layoutManager = new GridLayoutManager(this, 4);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int mod = position % 6;
if(position == 0 || position == 1)
return 2;
else if(position < 6)
return 1;
else if(mod == 0 || mod == 1)
return 2;
else
return 1;
}
});
recyclerView.setLayoutManager(layoutManager);
J'espère que ce travail pour vous!
Il y a comment ça marche dans mon projet j'ai différentes hauteurs de cellules et aussi en-tête
adaptateur:
public class AdapterRecViewMain
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<BaseMarkerElement> mainCardList;
private final int HEADER_VIEW = 0;
private final int FOOTER_VIEW = 1;
public AdapterRecViewMain() {
}
public void setData(List<BaseMarkerElement> mainCardList) {
this.mainCardList = mainCardList;
}
@Override public int getItemViewType(int position) {
if (position == 0) {
return HEADER_VIEW;
}
return FOOTER_VIEW;
}
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
if (type == FOOTER_VIEW) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.card_main_activity, viewGroup, false);
return new MainCardViewHolder(v);
} else {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.header_view_main_activity, viewGroup, false);
return new HeaderViewHolder(v);
}
}
@Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int positionItem) {
final int position = viewHolder.getAdapterPosition();
if (viewHolder instanceof HeaderViewHolder) {
StaggeredGridLayoutManager.LayoutParams layoutParams =
(StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();
layoutParams.setFullSpan(true);
BaseMarkerElement item = mainCardList.get(position);
if (item instanceof HeaderView) {
HeaderView header = (HeaderView) mainCardList.get(position);
// need to add implementation
}
} else if (viewHolder instanceof MainCardViewHolder) {
MainCardViewHolder currentView = (MainCardViewHolder) viewHolder;
CardMainActivity currentCard = (CardMainActivity) mainCardList.get(position);
currentView.ivMainCard.setImageResource(currentCard.getIvMainCard());
currentView.tvBrandName.setText(currentCard.getTvBrandName());
currentView.tvPrice.setText(currentCard.getTvPrice());
currentView.tvType.setText(currentCard.getTvType());
}
}
@Override public int getItemCount() {
return mainCardList.size();
}
private class MainCardViewHolder extends RecyclerView.ViewHolder {
ImageView ivMainCard;
TextView tvBrandName;
TextView tvType;
TextView tvPrice;
MainCardViewHolder(View view) {
super(view);
ivMainCard = (ImageView) view.findViewById(R.id.imageViewMainCard);
tvBrandName = (TextView) view.findViewById(R.id.tvBrandName);
tvType = (TextView) view.findViewById(R.id.tvType);
tvPrice = (TextView) view.findViewById(R.id.tvPrice);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
}
}
}
Dans votre activité:
private AdapterRecViewMain adapter;
private RecyclerView rvMain;
@Override protected void onResume() {
super.onResume();
Logger.logGeneral("onResume()");
if (adapter == null) {
setUpRecView();
}
}
private void setUpRecView() {
adapter = new AdapterRecViewMain();
adapter.setData(controller.loadData());
rvMain = (RecyclerView) findViewById(R.id.rvMain);
final StaggeredGridLayoutManager layoutManager =
new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
rvMain.setLayoutManager(layoutManager);
rvMain.addOnScrollListener(scrollListener);
rvMain.setAdapter(adapter);
adapter.notifyDataSetChanged();
rvMain.invalidate();
}
Je suppose que la meilleure façon de faire est d'utiliser la vue du recycleur. De plus, il est préférable à la liste/grille pour les performances
Les liens ci-dessous peuvent être très utiles - Tous sont liés à la vue bidirectionnelle par Lucas
https://github.com/lucasr/twoway-view
Avez-vous essayé un RecyclerView en combinaison avec un StaggeredGridLayoutManager ?
Cette combinaison se traduit par quelque chose comme ceci: vidéo .
Je pense que c'est ce que vous recherchez.
Créez deux fichiers XML différents et gonflez en fonction de la position dans votre adaptateur comme ci-dessous.
if(position%2==0){
//Inflate Even number layout with 4 images
}else{
//Inflate ODD number layout with 2 images
}
Essaye ça ,
https://github.com/etsy/AndroidStaggeredGrid
Vue en grille décalée,
Extrêmement simple, facile à utiliser.