J'ai une mise en page Android qui a une scrollView
avec un certain nombre d'éléments avec en elle. Au bas de la scrollView
, j'ai une listView
qui est ensuite renseignée par un adaptateur.
Le problème que je rencontre est qu'Android exclut la listView
de la scrollView
car la scrollView
a déjà une fonction de défilement. Je veux que la listView
soit aussi longue que le contenu et que la vue de défilement principale puisse défiler.
Comment puis-je obtenir ce comportement?
Voici ma mise en page principale:
<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >
<LinearLayout
Android:id="@+id/foodItemActvity_linearLayout_fragments"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
</LinearLayout>
</ScrollView>
J'ajoute ensuite par programmation mes composants à linearlayour avec l'id: foodItemActvity_linearLayout_fragments
. Vous trouverez ci-dessous l’une des vues chargées dans cette représentation linéaire. C'est celui qui me pose problème avec les parchemins.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
<TextView
Android:id="@+id/fragment_dds_review_textView_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Reviews:"
Android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
Android:id="@+id/fragment_dds_review_listView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
</ListView>
</LinearLayout>
Mon adaptateur remplit alors cette vue liste.
Voici une image du visualiseur de hiérarchie Android lorsque je clique sur le scrollView principal:
Comme vous pouvez le constater, cela exclut les avis listView.
Je devrais pouvoir faire défiler la page vers le bas et voir 8 avis, mais au lieu de cela, il ne me montre que les 3, et je peux faire défiler la toute petite partie où se trouvent les avis. Je veux un défilement de page global
Le solution la plus courte et la plus simple pour le ListView dans un problème ScrollView.
Vous ne devez rien faire de spécial dans le fichier layout.xml ni manipuler quoi que ce soit sur le ScrollView parent. _ {Vous devez seulement gérer l'enfant ListView}. Vous pouvez également utiliser ce code pour utiliser tout type de vue enfant à l'intérieur d'un objet ScrollView et effectuer des opérations tactiles.
Ajoutez simplement ces lignes de code dans votre classe Java:
ListView lv = (ListView) findViewById(R.id.layout_lv);
lv.setOnTouchListener(new OnTouchListener() {
// Setting on Touch Listener for handling the touch inside ScrollView
@Override
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of child view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
Si vous mettez ListView à l'intérieur d'un ScrollView, le ListView ne s'étire pas à sa hauteur maximale}. Vous trouverez ci-dessous une méthode pour résoudre ce problème.
/**** Method for Setting the Height of the ListView dynamically.
**** Hack to fix the issue of not showing all the items of the ListView
**** when placed inside a ScrollView ****/
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
Pour utiliser cette méthode, il suffit de passer le ListView à l'intérieur de cette méthode:
ListView list = (ListView) view.findViewById(R.id.ls);
setListViewHeightBasedOnChildren(list);
Pour utiliser avec ExpandableListView - crédit Benny
ExpandableListView: view = listAdapter.getView(0, view, listView);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.MATCH_PARENT, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);
Pour ListView avec des éléments variables height, utilisez le lien ci-dessous:
ListView dans ScrollView ne défile pas sur Android
Pour que la bibliothèque soit directement implémentée dans votre code - crédit Paolo Rotolo
La réponse est simple et je suis surpris qu'il n'ait pas encore été répondu ici.
Utilisez un Header View
ou/et Footer View
sur la liste elle-même . Ne mélangez pas une ScrollView
avec une ListView
ou quoi que ce soit qui puisse défiler. Il est destiné à être utilisé avec les en-têtes et les pieds de page :)
Essentiellement, prenez tout le contenu au-dessus de votre ListView, placez-le dans un autre fichier .xml en tant que mise en page, puis gonflez-le dans le code et ajoutez-le à la liste en tant qu'en-tête.
c'est à dire.
View header = getLayoutInflater().inflate(R.layout.header, null);
View footer = getLayoutInflater().inflate(R.layout.footer, null);
listView.addHeaderView(header);
listView.addFooterView(footer);
Je sais que ça fait si longtemps, mais j'ai aussi ce problème, j'ai essayé cette solution et ça marche. Donc, je suppose que cela peut aider les autres aussi.
J'ajoute Android: fillViewport = "true" dans la mise en page XML de scrollView . Donc, dans l'ensemble, mon ScrollView sera comme ceci.
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/scrollView6"
Android:fillViewport="true">
Et cela fonctionne comme par magie pour moi. le ListView situé à l'intérieur de mon ScrollView s'agrandit à sa taille.
Voici l'exemple de code complet pour ScrollView et ListView.
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/scrollView6" Android:fillViewport="true">
<LinearLayout
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
....
<ListView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/lv_transList" Android:layout_gravity="top"
Android:layout_marginTop="5dp"/>
....
</LinearLayout>
</ScrollView>
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>
Dans le fichier Java Créez un objet de votre customListview au lieu de ListView, comme: NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);
public static void setListViewHeightBasedOnChildren(ListView listView) {
// 获取ListView对应的Adapter
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0); // 计算子项View 的宽高
totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
listView.setLayoutParams(params);
}
vous pouvez utiliser ce code pour listview dans scrollview
Vous pouvez le résoudre en ajoutant Android:fillViewport="true"
à votre ScrollView.
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/white"
Android:fillViewport="true"
Android:scrollbars="vertical">
<ListView
Android:id="@+id/statusList"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:animationCache="false"
Android:divider="@null"
Android:scrollingCache="false"
Android:smoothScrollbar="true" />
</ScrollView>
avant d’utiliser cette propriété, il n’y avait qu’un enfant de ma liste. après utilisation, toutes les lignes ou enfants de la liste sont visibles.
Ce code résoudra votre problème si vous avez implémenté seulement un ListView dans un code.
Si vous utilisez RelativeLayout comme enfant ListView, ce code renvoie une exception NullPointerException ici listItem.measure (0, 0); , à cause de RelativeLayout.Et la solution est de placer votre Relativelayout dans un LinearLayout et tout se passera bien.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Je vais le laisser ici au cas où quelqu'un serait confronté au même problème. Je devais mettre un ListView à l'intérieur d'un ScrollView. ListView avec en-tête n'était pas une option pour plusieurs raisons. Ni était une option d'utiliser LinearLayout au lieu de ListView. J'ai donc suivi la solution acceptée, mais cela n'a pas fonctionné, car les éléments de la liste avaient une mise en page complexe avec plusieurs lignes et chaque élément de la vue liste avait une hauteur variable. La taille n'a pas été mesurée correctement. La solution consistait à mesurer chaque élément de la méthode getView () de ListView Adapter.
@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
. . .
view.setTag(holder);
} else holder = (ViewHolder)view.getTag();
. . .
// measure ListView item (to solve 'ListView inside ScrollView' problem)
view.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
return view;
}
Vous pouvez facilement mettre ListView dans ScrollView! Il suffit de changer la hauteur de ListView par programmation , comme ceci:
ViewGroup.LayoutParams listViewParams = (ViewGroup.LayoutParams)listView.getLayoutParams();
listViewParams.height = 400;
listView.requestLayout();
Cela fonctionne parfaitement!
Fait après beaucoup de R & D:
fragment_one.xml devrait ressembler à:
<?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:id="@+id/scrollViewParent"
Android:orientation="vertical" >
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="400dip" >
<ListView
Android:id="@+id/listView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
<View
Android:id="@+id/customView"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:background="@Android:color/transparent" />
</RelativeLayout>
<!-- Your other elements are here -->
</LinearLayout>
</ScrollView>
Votre classe Java de FragmentOne.Java ressemble à:
private ListView listView;
private View customView
onCreateView
listView = (ListView) rootView.findViewById(R.id.listView);
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);
customView.setOnTouchListener(new View.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.
scrollViewParent.requestDisallowInterceptTouchEvent(true);
// Disable touch on transparent view
return false;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(false);
return true;
case MotionEvent.ACTION_MOVE:
scrollViewParent.requestDisallowInterceptTouchEvent(true);
return false;
default:
return true;
}
}
});
Ne faites rien dans Parent ScrollView. Faites ceci uniquement à l'enfant ListView. Tout fonctionnera parfaitement.
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mScrollView.requestDisallowInterceptTouchEvent(true);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_UP:
mScrollView.requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
});
J'ai eu un problème similaire au problème posé par l'affiche originale - comment faire défiler la liste dans le défilement - et cette réponse a résolu mon problème . Désactiver le défilement d'un ListView contenu dans un ScrollView
Je n'ai pas appelé de nouveaux fragments dans des mises en page existantes ou quoi que ce soit, comme le faisait l'OP, afin que mon code ressemble à ceci:
<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >
<LinearLayout
Android:id="@+id/foodItemActvity_linearLayout_fragments"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
<TextView
Android:id="@+id/fragment_dds_review_textView_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Reviews:"
Android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
Android:id="@+id/my_listView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
</ListView>
</LinearLayout>
</ScrollView>
Essentiellement, je vérifie la longueur de la liste avant de l'appeler et, lorsque je l'appelle, je la fixe à cette longueur. Dans votre classe Java, utilisez cette fonction:
public static void justifyListViewHeightBasedOnChildren (ListView listView) {
ListAdapter adapter = listView.getAdapter();
if (adapter == null) {
return;
}
ViewGroup vg = listView;
int totalHeight = 0;
for (int i = 0; i < adapter.getCount(); i++) {
View listItem = adapter.getView(i, null, vg);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams par = listView.getLayoutParams();
par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
listView.setLayoutParams(par);
listView.requestLayout();
}
Et appelez la fonction comme ceci:
justifyListViewHeightBasedOnChildren(listView);
Le résultat est une liste sans barre de défilement, la totalité de la liste étant affichée, qui défile avec la barre de défilement de la vue.
Vous pouvez tout mettre en disposition linéaire. C'est-à-dire, créez une disposition linéaire et il aura 2 enfants, scrollview et une autre disposition linéaire Donnez-leur des poids de mise en page et voilà:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >
<ScrollView
Android:layout_width="fill_parent"
Android:layout_height="0dip" Android:layout_weight="0.8">
<LinearLayout
Android:id="@+id/seTaskActivityRoot"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:background="@color/white"
Android:orientation="vertical" >
<TextView
Android:id="@+id/textView1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:text="@string/taskName" />
<Spinner
Android:id="@+id/seTaskPrioritiesSP"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1" />
<TextView
Android:id="@+id/textView4"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:text="@string/taskTargetInNumeric" />
<Spinner
Android:id="@+id/seTaskUnitsSP"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1" />
<TextView
Android:id="@+id/textView6"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:text="@string/newTaskCurrentStatus" />
<EditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:ems="10"
Android:hint="@string/addTaskCurrentStatus"
Android:inputType="numberDecimal" />
</LinearLayout>
</ScrollView>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="0dip"
Android:orientation="vertical" Android:layout_weight="0.2">
<TextView
Android:id="@+id/textView8"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="TextView" />
<ListView
Android:id="@+id/logList"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Comme d'autres l'avaient déjà mentionné, n'utilisez pas ListView dans un ScrollView.
Pour contourner le problème, vous pouvez utiliser LinearLayout, tout en conservant un aspect ordonné - remplissez votre LinearLayout avec un adaptateur, comme vous le feriez avec un ListView
Vous pouvez utiliser cette classe comme remplacement de LinearLayout prenant en charge les adaptateurs.
import Android.content.Context;
import Android.database.DataSetObserver;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.BaseAdapter;
import Android.widget.LinearLayout;
public class AdaptableLinearLayout extends LinearLayout {
private BaseAdapter mAdapter;
private int mItemCount = 0;
private boolean mDisableChildrenWhenDisabled = false;
private int mWidthMeasureSpec;
private int mHeightMeasureSpec;
public AdaptableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public BaseAdapter getAdapter() {
return mAdapter;
}
public void setAdapter(BaseAdapter adapter) {
mAdapter = adapter;
adapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
updateLayout();
super.onChanged();
}
@Override
public void onInvalidated() {
updateLayout();
super.onInvalidated();
}
});
updateLayout();
}
private void updateLayout() {
mItemCount = mAdapter.getCount();
requestLayout();
invalidate();
}
/**
* set size for the current View
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidthMeasureSpec = widthMeasureSpec;
mHeightMeasureSpec = heightMeasureSpec;
removeAllViewsInLayout();
for (int i = 0; i < mItemCount; i++) {
makeAndAddView(i);
}
}
private View makeAndAddView(int position) {
View child;
// Nothing found in the recycler -- ask the adapter for a view
child = mAdapter.getView(position, null, this);
// Position the view
setUpChild(child, position);
return child;
}
private void setUpChild(View child, int position) {
ViewGroup.LayoutParams lp = child.getLayoutParams();
if (lp == null) {
lp = generateDefaultLayoutParams();
}
addViewInLayout(child, position, lp);
// Get measure specs
int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), lp.height);
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);
// Measure child
child.measure(childWidthSpec, childHeightSpec);
int childLeft;
int childRight;
// Position vertically based on gravity setting
int childTop = getPaddingTop() + ((getMeasuredHeight() - getPaddingBottom() - getPaddingTop() - child.getMeasuredHeight()) / 2);
int childBottom = childTop + child.getMeasuredHeight();
int width = child.getMeasuredWidth();
childLeft = 0;
childRight = childLeft + width;
child.layout(childLeft, childTop, childRight, childBottom);
if (mDisableChildrenWhenDisabled) {
child.setEnabled(isEnabled());
}
}
}
Vous ne devez jamais utiliser un objet ScrollView avec un objet ListView, car ListView prend en charge son propre défilement vertical. Plus important encore, cette opération annule toutes les optimisations importantes dans ListView pour traiter les grandes listes, car cela oblige effectivement ListView à afficher la liste complète des éléments pour remplir le conteneur infini fourni par ScrollView.
http://developer.Android.com/reference/Android/widget/ScrollView.html
Mettre à jour
<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >
<LinearLayout
Android:id="@+id/foodItemActvity_linearLayout_fragments"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
</LinearLayout>
à
<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >
<LinearLayout
Android:id="@+id/foodItemActvity_linearLayout_fragments"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
</LinearLayout>
Le point ici est que vous essayez de définir la hauteur à 0dp (fixe)
trouvé une solution pour scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> listview dynamique, mais je ne suis pas l'auteur. il y a des bugs, mais au moins ça marche
public class CustomPager extends ViewPager {
private View mCurrentView;
public CustomPager(Context context) {
super(context);
}
public CustomPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void measureCurrentView(View currentView) {
mCurrentView = currentView;
this.post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
public int measureFragment(View view) {
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
}
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
private int mCurrentPosition = -1;
public MyPagerAdapter(FragmentManager fm) {
super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
this.fragments = new ArrayList<Fragment>();
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
fragments.add(new FourthFragment());
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition) {
Fragment fragment = (Fragment) object;
CustomPager pager = (CustomPager) container;
if (fragment != null && fragment.getView() != null) {
mCurrentPosition = position;
pager.measureCurrentView(fragment.getView());
}
}
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
fragments disposition peut être n'importe quoi
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
Android:orientation="vertical"
Android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">
<ListView
Android:id="@+id/lv1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#991199"/>
</LinearLayout>
alors quelque part juste
lv = (ListView) view.findViewById(R.id.lv1);
lv.setAdapter(arrayAdapter);
setListViewHeightBasedOnChildren(lv);
}
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
LinearLayout.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Mon exigence est d'inclure un ListView d'éléments de taille égale dans un ScrollView. J'ai essayé quelques-unes des autres solutions énumérées ici, aucune ne semblait dimensionner correctement le ListView (trop peu d'espace ou trop). Voici ce qui a fonctionné pour moi:
public static void expandListViewHeight(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
ViewGroup.LayoutParams params = listView.getLayoutParams();
listView.measure(0, 0);
params.height = listView.getMeasuredHeight() * listAdapter.getCount() + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
J'espère que ça aide quelqu'un.
En XML:
<com.example.util.NestedListView
Android:layout_marginTop="10dp"
Android:id="@+id/listview"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:divider="@null"
Android:layout_below="@+id/rl_delivery_type" >
</com.example.util.NestedListView>
En Java:
public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener {
private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;
public NestedListView(Context context, AttributeSet attrs) {
super(context, attrs);
listViewTouchAction = -1;
setOnScrollListener(this);
setOnTouchListener(this);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, -1);
}
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty()) {
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
}
newHeight += getDividerHeight() * listPosition;
}
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
if (newHeight > heightSize) {
newHeight = heightSize;
}
}
} else {
newHeight = getMeasuredHeight();
}
setMeasuredDimension(getMeasuredWidth(), newHeight);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, 1);
}
}
return false;
}
}
Ok, voici ma réponse. La méthode qui corrige la hauteur de ListView est suffisamment fermée, mais pas parfaite. Si la plupart des objets ont la même hauteur, cela fonctionne bien. Mais au cas où ce ne serait pas le cas, il y aurait un gros problème. J'ai essayé plusieurs fois, et quand j'ai mis la valeur de listItem.getMeasureHeight et de listItem.getMeasuerWidth dans le journal, j'ai vu que les valeurs de largeur variaient beaucoup, ce qui n'est pas prévu ici, car tout l'élément dans la même liste devrait avoir la même largeur. Et voilà le bogue:
Certaines utilisaient la mesure (0, 0), ce qui rendait la vue non liée, dans les deux sens, et la largeur devenait sauvage. Certains ont essayé d’obtenirWidth of listView, mais ensuite, il renvoie 0, sans signification.
Lorsque je lis plus en détail la manière dont Android rend la vue, je me rends compte que toutes ces tentatives ne permettent pas d’obtenir la réponse recherchée, à moins que cette fonction ne soit exécutée après le rendu de la vue.
Cette fois, j'utilise getViewTreeObserver sur le ListView que je veux corriger, puis addOnGlobalLayoutListener. Dans cette méthode, je déclare un nouvel objet OnGlobalLayoutListener, dans lequel, cette fois, getWidth renvoie la largeur réelle de ListView.
private void getLayoutWidth(final ListView lv, final int pad){
//final ArrayList<Integer> width = new ArrayList<Integer>();
ViewTreeObserver vto = lv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
lv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//width.add(layout.getMeasuredWidth());
int width = lv.getMeasuredWidth();
ListUtils.setDynamicHeight(lv, width, pad);
}
});
}
public static class ListUtils {
//private static final int UNBOUNDED = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
public static void setDynamicHeight(ListView mListView, int width, int pad) {
ListAdapter mListAdapter = mListView.getAdapter();
mListView.getParent();
if (mListAdapter == null) {
// when adapter is null
return;
}
int height = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(width - 2*pad, View.MeasureSpec.EXACTLY);
for (int i = 0; i < mListAdapter.getCount(); i++) {
View listItem = mListAdapter.getView(i, null, mListView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
//listItem.measure(UNBOUNDED, UNBOUNDED);
height += listItem.getMeasuredHeight() + 2*pad;
Log.v("ViewHeight :", mListAdapter.getClass().toString() + " " + listItem.getMeasuredHeight() + "--" + listItem.getMeasuredWidth());
}
ViewGroup.LayoutParams params = mListView.getLayoutParams();
params.height = height + (mListView.getDividerHeight() * (mListAdapter.getCount() - 1));
mListView.setLayoutParams(params);
mListView.requestLayout();
}
}
Le pavé de valeur est le remplissage que j'ai défini dans la présentation ListView.
en utilisant ce ListView a travaillé pour moi
package net.londatiga.Android.widget;
import Android.util.AttributeSet;
import Android.view.ViewGroup;
import Android.widget.ListView;
import Android.content.Context;
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT Android!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
et en xml
<com.pakagename.ExpandableHeightListView
Android:id="@+id/expandableHeightListView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</com.Example.ExpandableHeightListView>
et dans MainActivity
ExpandableHeightListView listView = new ExpandableHeightListView(this);
listview=(ExpandableHeightListView)findViewById(R.id.expandableHeightListView);
listView.setAdapter(adapter); //set your adaper
listView.setExpanded(true);
Reportez-vous à cet article pour plus d'informations et savoir comment conserver gridview dans la vue par défilement
Si, pour une raison quelconque, vous ne souhaitez pas utiliser addHeaderView
et addFooterView
, par ex. Lorsque vous avez plusieurs listes, une bonne idée serait de réutiliser ListAdapter
pour remplir une simple LinearLayout
afin de ne pas avoir de fonctionnalité de défilement.
Si vous possédez déjà un fragment entier dérivé de ListFragment
et souhaitez le convertir en un fragment similaire avec LinearLayout
simple sans faire défiler (par exemple, pour le mettre dans ScrollView), vous pouvez implémenter un fragment d'adaptateur comme ceci:
// converts listFragment to linearLayout (no scrolling)
// please call init() after fragment is inflated to set listFragment to convert
public class ListAsArrayFragment extends Fragment {
public ListAsArrayFragment() {}
private ListFragment mListFragment;
private LinearLayout mRootView;
// please call me!
public void init(Activity activity, ListFragment listFragment){
mListFragment = listFragment;
mListFragment.onAttach(activity);
mListFragment.getListAdapter().registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
refreshView();
}
});
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create an empty vertical LinearLayout as the root view of this fragment
mRootView = new LinearLayout(getActivity());
mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mRootView.setOrientation(LinearLayout.VERTICAL);
return mRootView;
}
// reusing views for performance
// todo: support for more than one view type
ArrayList<View> mViewsToReuse = new ArrayList<>();
ArrayList<View> mCurrentViews = new ArrayList<>();
// re-add views to linearLayout
void refreshView(){
// remove old views from linearLayout and move them to mViewsToReuse
mRootView.removeAllViews();
mViewsToReuse.addAll(mCurrentViews);
mCurrentViews.clear();
// create new views
for(int i=0; i<mListFragment.getListAdapter().getCount(); ++i){
View viewToReuse = null;
if(!mViewsToReuse.isEmpty()){
viewToReuse = mViewsToReuse.get(mViewsToReuse.size()-1);
mViewsToReuse.remove(mViewsToReuse.size()-1);
}
final View view = mListFragment.getListAdapter().getView(i, viewToReuse, mRootView);
ViewGroup.LayoutParams oldParams = view.getLayoutParams();
view.setLayoutParams(new LinearLayout.LayoutParams(oldParams.width, oldParams.height));
final int finalI = i;
// pass click events to listFragment
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListFragment.onListItemClick(null, view, finalI, finalI);
}
});
mRootView.addView(view);
mCurrentViews.add(view);
}
}
Vous pouvez également vouloir transférer onCreate
, onPause
, onResume
, etc. vers le fragment d'origine en fonction de vos besoins ou essayez l'héritage au lieu de la composition (mais remplacez certaines méthodes afin que le fragment d'origine ne soit pas réellement lié à la hiérarchie de présentation); mais je voulais isoler le fragment original autant que possible, car nous n'avons besoin que d'extraire sa ListAdapter
. Si vous appelez la variable setListAdapter
du fragment original dans onAttach
, c'est probablement suffisant.
Voici comment utiliser ListAsArrayFragment
pour inclure OriginalListFragment
sans défilement. Dans l'activité parent onCreate
:
ListAsArrayFragment fragment = (ListAsArrayFragment) getFragmentManager().findFragmentById(R.id.someFragmentId);
OriginalListFragment originalFragment = new OriginalListFragment();
fragment.init(this, originalFragment);
// now access originalFragment.getListAdapter() to modify list entries
// and remember to call notifyDatasetChanged()
trouvé une solution pour scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> listview dynamique, mais je ne suis pas l'auteur.
public class CustomPager extends ViewPager {
private View mCurrentView;
public CustomPager(Context context) {
super(context);
}
public CustomPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void measureCurrentView(View currentView) {
mCurrentView = currentView;
this.post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
public int measureFragment(View view) {
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
}
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
private int mCurrentPosition = -1;
public MyPagerAdapter(FragmentManager fm) {
super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
this.fragments = new ArrayList<Fragment>();
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
fragments.add(new FourthFragment());
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition) {
Fragment fragment = (Fragment) object;
CustomPager pager = (CustomPager) container;
if (fragment != null && fragment.getView() != null) {
mCurrentPosition = position;
pager.measureCurrentView(fragment.getView());
}
}
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
fragments disposition peut être n'importe quoi
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
Android:orientation="vertical"
Android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">
<ListView
Android:id="@+id/lv1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#991199"/>
</LinearLayout>
alors quelque part juste
lv = (ListView) view.findViewById(R.id.lv1);
lv.setAdapter(arrayAdapter);
setListViewHeightBasedOnChildren(lv);
}
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
LinearLayout.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Cela a fonctionné pour moi ( link1 , link2 ):
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 = View.MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
Dans votre fichier de mise en page
<ScrollView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:fillViewport="true">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<!-- com.Example Changed with your Package name -->
<com.thedeveloperworldisyours.view.NonScrollListView
Android:id="@+id/lv_nonscroll_list"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</com.thedeveloperworldisyours.view.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>
Créez un objet de votre customListview au lieu de ListView comme:
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);
Ne mettez JAMAIS une ListView
dans une ScrollView
! Vous pouvez trouver plus d'informations à ce sujet sur Google . Dans votre cas, utilisez une LinearLayout
au lieu de ListView
et ajoutez les éléments par programme.
Il suffit d'appeler cette fonction après avoir assigné l'adaptateur à listview
public static void setListViewHeightBasedOnChildren
(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0) view.setLayoutParams(new
ViewGroup.LayoutParams(desiredWidth,
ViewGroup.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() *
(listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Pour utiliser list-view dans Scroll-view, vous pouvez suivre ces étapes qui ont fonctionné pour moi:
1) Créez NonScrollListView Java qui désactive la propriété de défilement par défaut de list-view. et le code est ci-dessous
package your-package-structure;
import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.ViewGroup;
import Android.widget.ListView;
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();
}
}
2) Créez maintenant un fichier XML contenant NestedScrollView
et NonScrollListView
à l'intérieur de cette liste pour lister vos éléments Cela fera défiler tout votre écran avec toutes les vues.
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:orientation="vertical">
<ViewFlipper
Android:id="@+id/v_flipper"
Android:layout_width="match_parent"
Android:layout_height="130dp">
</ViewFlipper>
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="SHOP"
Android:textSize="15dp"
Android:textStyle="bold"
Android:gravity="center"
Android:padding="5dp"
Android:layout_marginTop="15dp"
Android:layout_marginBottom="5dp"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"/>
<View
Android:layout_width="match_parent"
Android:layout_height="1dp"
Android:layout_marginBottom="8dp"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:background="#ddd"/>
</LinearLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:layout_weight="1"
>
<com.abc.xyz.NonScrollListView
Android:id="@+id/listview"
Android:divider="@null"
Android:layout_width="match_parent"
Android:layout_marginBottom="10dp"
Android:layout_height="match_parent"
Android:padding="8dp">
</com.abc.xyz.NonScrollListView>
</LinearLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="bottom">
<include layout="@layout/footer" />
</LinearLayout>
</LinearLayout>
3) Maintenant dans la classe Java, home.Java définit NonScrollListView
au lieu de Listview
.
package comabc.xyz.landscapeapp;
import Android.content.Intent;
import Android.support.annotation.NonNull;
import Android.support.annotation.Nullable;
import Android.support.v4.app.Fragment;
import Android.os.Bundle;
import Android.support.v4.app.FragmentTransaction;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.AdapterView;
import Android.widget.Button;
import Android.widget.ImageView;
import Android.widget.ListView;
import Android.widget.Toast;
import Android.widget.Toolbar;
import Android.widget.ViewFlipper;
public class home s'étend au fragment { int pos = 0; ViewFlipper v_flipper;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_home, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
customAdapter customAdapter = new customAdapter(getActivity());
listView.setAdapter(customAdapter);
listView.setFocusable(false);
customAdapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("listview click", "onItemClick: ");
/* FragmentTransaction fr = getFragmentManager().beginTransaction().replace(R.id.fragment_container, new productdisplay());
fr.putExtra("Position", position);
fr.addToBackStack("tag");
fr.commit();*/
Intent intent = new Intent(getActivity(), productdisplay.class);
intent.putExtra("Position", position);
startActivity(intent);
}
});
//image slider
int images[] = {R.drawable.slide1, R.drawable.slide2, R.drawable.slide3};
v_flipper = view.findViewById(R.id.v_flipper);
for (int image : images) {
flipperImages(image);
}
}
private void flipperImages(int image) {
ImageView imageView = new ImageView(getActivity());
imageView.setBackgroundResource(image);
v_flipper.addView(imageView);
v_flipper.setFlipInterval(4000);
v_flipper.setAutoStart(true);
v_flipper.setInAnimation(getActivity(), Android.R.anim.slide_in_left);
v_flipper.setOutAnimation(getActivity(), Android.R.anim.slide_out_right);
}
}
Note: J'ai utilisé Fragments
ici.
Il suffit de définir la valeur de la hauteur requise dans un attribut height de listview dans une vue de défilement parent. Il défilera avec l'élément enfant des autres parents.