J'essaie de faire une mise en page comme ceci:
Le problème est que je ne veux pas que les ListViews puissent défiler. Je veux qu’ils soient aussi hauts que nécessaire et que tout l’écran soit défilable. Si je règle la hauteur de ListView à wrap_content
, cela ne fonctionnera pas. La seule façon de le faire fonctionner est de définir une hauteur spécifique - mais je ne sais pas combien d'éléments seront dans ListView.
Je sais que je ne devrais pas mettre ListView dans ScrollView - mais je ne veux pas que ListView puisse défiler, mais pour afficher tous les éléments.
Peut-être qu'il y a un meilleur moyen de le faire fonctionner?
Vous créez un ListView personnalisé qui n'est pas Scrollable
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
Dans votre fichier de ressources de mise en page
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fadingEdgeLength="0dp"
Android:fillViewport="true"
Android:overScrollMode="never"
Android:scrollbars="none" >
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<!-- com.Example Changed with your Package name -->
<com.Example.NonScrollListView
Android:id="@+id/lv_nonscroll_list"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_below="@+id/lv_nonscroll_list" >
<!-- Your another layout in scroll view -->
</RelativeLayout>
</RelativeLayout>
</ScrollView>
En fichier Java
Créez un objet de votre customListview au lieu de ListViewlike:
NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);
Il n'y a pas du tout besoin d'utiliser une listview.
Si vous y réfléchissez vraiment, une listview peut être remplacée par une représentation linéaire dans votre cas. L’adaptateur est identique, mais au lieu d’attacher l’adaptateur à votre listview, appelez simplement la fonction getView de l’adaptateur dans une boucle for pour vos données et ajoutez les vues extraites à votre affichage linéaire vertical.
Cependant, cette approche n'est recommandée que si vous avez un petit nombre d'éléments dans votre liste et que votre représentation d'affichage de ces éléments ne nécessite pas beaucoup de mémoire.
La meilleure façon de procéder (en 2017) consiste à utiliser un RecyclerView avec un NestedScrollView. Aucun piratage requis et cela fonctionne comme vous le souhaitez.
Eh bien, il y a un gars cool sur Android nommé Mark Murphy de CommonsWare et il a construit un composant très utile nommé CWAC Merge Adapter qui vous permet de faire ce dont vous avez besoin. Vous devrez ajouter les vues de manière dynamique et non à partir de XML; mais compte tenu de votre interface utilisateur simple, cela ne devrait pas être un problème. Je l'utilise pour ce type de cas où je n'ai aucune idée du type de données que je suis censé faire défiler.
Si vous ne voulez pas l'utiliser (pour des raisons de licence peut-être), vous pouvez y avoir une seule liste (au lieu de ces 2 vues consécutives) et remplacer getItemViewsCount
, getItemViewType
et getView
afin de donner la disposition ci-dessus. Si vous recherchez Android listview different rows
sur Google, vous trouverez des informations utiles. Par exemple ce lien ou celui-ci .
Cependant, je choisirais un adaptateur de fusion.
Choisissez le ListView que vous voulez faire défiler, puis ajoutez la méthode 'setOnTouchListener' pour que le système insère automatiquement le défilement dans le ListView.
final ListView listview = (ListView) findViewById(R.id.list);
listview.setOnTouchListener(new ListView.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle ListView touch events.
v.onTouchEvent(event);
return true;
}
});
listview.setClickable(true);
J'espère que ça marche pour toi
J'ai une solution facile s'il est possible de calculer la hauteur de votre élément/largeur ... Il vous suffit de créer une représentation linéaire du parent de ListView, puis de fixer le parent hauteur à partir de Java.
Supposons que vous ayez besoin de concevoir cette vue ... Maintenant, la taille de la mise en page parent est définie par Java ...
final LinearLayout parent=(LinearLayout)findViewById(R.id.parent);
final ListView listview=(ListView)findViewById(R.id.listview);
parent.setLayoutParams(new LinearLayout.LayoutParams(parent.getLayoutParams().width, dpToPx( number_of_item_in_list * per_item_size_in_dp )));
//number_of_item_in_list is list side ~ listArray.size();
//per_item_size_in_dp = calculate item size in dp. Ex: 80dp
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
c'est tout :)