J'ai actuellement besoin d'utiliser un RecyclerView (ou ListView) mais le nombre d'éléments est fixé à 4. Je veux que ces 4 éléments utilisent également l'espace disponible à l'écran. RecyclerView est la seule vue à l'écran, à l'exception de la barre d'applications. C'est à dire. RecyclerView a layout_height
défini sur match_parent
. J'ai choisi RecyclerView car les éléments ont des dispositions différentes en fonction de l'état du modèle.
Je ne l'ai pas encore consultée, mais je suis sûr que je peux définir la hauteur par programmation en code Java pour chaque élément. Mais cela semble inélégant si je peux le spécifier dans le XML. Des questions similaires à ma droite, au moment où j'écris ceci, répondent à cette question.
J'ai essayé ce qui suit dans le fichier item_layout.xml, de la façon dont layout_weight
est utilisé dans d'autres scénarios:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_weight="1"
Android:layout_height="0dp">...</LinearLayout>
Mais alors rien ne s'affiche à l'écran.
Ce que j'aimerais savoir, c'est: puis-je le faire dans le XML de présentation avec layout_weight
ou quelque chose d'autre? Si c'est le cas, comment?
Comme le API reference dit, layout_weight
est un attribut de LinearLayout
, donc ne peut pas être utilisé avec d'autres ViewGroups, comme par exemple RecyclerView
et ListView
. Au lieu de cela, vous devez définir la hauteur de l'élément par programme.
Puisque vous semblez préoccupé par la propreté de votre code, je pense que c'est une solution plutôt élégante au cas où vous utiliseriez une RecyclerView
:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.item_list, null);
int height = parent.getMeasuredHeight() / 4;
int width = parent.getMeasuredWidth();
view.setLayoutParams(new RecyclerView.LayoutParams(width, height));
return new ViewHolder(view);
}
Essayez ceci, travaillez pour moi
int weight = 3; //number of parts in the recycler view.
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
rowView.getLayoutParams().height = parent.getHeight() / weight;
return new ViewHolder(rowView);
}
J'ai rencontré ce problème, car j'avais un RecyclerView avec des entrées variables. Mon RecyclerView horizontal devait s'adapter à au moins trois vues sans déborder. J'ai donc conçu mes vues pour qu'elles soient redimensionnées à l'exécution afin de s'adapter à l'écran.
class MyRecyclerView extends RecyclerView.Adapter<ViewHolder> {
int mViewWidth;
public MyRecyclerView(Context context) {
mViewWidth = defineViewWidth(context);
}
private int defineViewWidth(Context context) {
int definedWidth = (int) context.getResources().getDimension(R.dimen.default_view_width);
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
if (definedWidth * 3 > dm.widthPixels) {
return dm.widthPixels / 3;
}
return definedWidth;
}
...
}
Une fois que vous avez défini une largeur, vous devez définir la largeur de la vue:
@Override
public ViewHolder onCreateViewHolder(ViewHolder holder, int position) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
ViewGroup.LayoutParams params = v.getLayoutParams();
params.width = mViewWidth;
v.setLayoutParams(params);
return new ViewHolder(v);
}
Vous pouvez facilement modifier cela pour vous assurer que votre RecyclerView s'adapte à autant d'éléments (verticalement ou horizontalement) que vous avez besoin.
Par ItemDecoration:
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int itemWidth = parent.getMeasuredWidth() / 7;
view.getLayoutParams().width = itemWidth;
}