J'ai des problèmes avec une variable ListView
à l'intérieur d'une ScrollView
. J'ai une activité qui a quelques EditTexts dans la partie supérieure puis un onglet hôte avec deux onglets qui ont chacun une liste. Lorsque les vues EditText sont activées, le clavier logiciel s’affiche et, dans la mesure où j’ai une vue ScrollView, le contenu peut défiler. Mais le problème survient quand il y a plus d'éléments dans ListViews (ceux dans les onglets), je ne peux pas faire défiler le ListView, même s'il y a plus d'éléments.
Voici le XML de mise en page:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:background="?backgroundImage"
Android:orientation="vertical">
<LinearLayout
Android:orientation="horizontal"
Android:layout_width="fill_parent"
Android:layout_height="50dip"
Android:layout_alignParentBottom="true"
Android:layout_margin="10dip"
Android:id="@+id/buttons">
<Button
Android:text="Save"
Android:layout_margin="2dip"
Android:textSize="20dip"
Android:id="@+id/btnSaveorUpdate"
Android:layout_height="wrap_content"
Android:layout_width="145dip"></Button>
<Button
Android:text="Cancel"
Android:layout_margin="2dip"
Android:textSize="20dip"
Android:id="@+id/btnCancelorDelete"
Android:layout_height="wrap_content"
Android:layout_width="145dip"></Button>
</LinearLayout>
<ScrollView
Android:layout_above="@id/buttons"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:fillViewport="true"
Android:layout_margin="10dip">
<LinearLayout
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:layout_margin="10dip">
<TextView
Android:text="Bill details"
Android:textColor="?textColorDark"
Android:layout_alignParentTop="true"
Android:id="@+id/txtEnterDetails"
Android:textSize="25dip"
Android:textStyle="bold"
Android:layout_height="wrap_content"
Android:layout_width="fill_parent"
Android:layout_marginBottom="2dip"></TextView>
<LinearLayout
Android:focusable="true"
Android:focusableInTouchMode="true"
Android:layout_width="0dip"
Android:layout_height="0dip" />
<EditText
Android:layout_width="fill_parent"
Android:hint="Enter data"
Android:inputType="numberDecimal"
Android:id="@+id/txtSample"
Android:textSize="@dimen/editText"
Android:layout_height="@dimen/editTextHeight"
Android:text=""></EditText>
<EditText
Android:layout_width="fill_parent"
Android:id="@+id/txtDescription"
Android:hint="Enter description"
Android:textSize="@dimen/editText"
Android:layout_height="@dimen/editTextHeight"
Android:inputType="text"
Android:text=""></EditText>
<EditText
Android:layout_width="fill_parent"
Android:id="@+id/txtComment"
Android:hint="Enter comment (if any)"
Android:textSize="@dimen/editText"
Android:layout_height="@dimen/editTextHeight"
Android:inputType="text"
Android:text=""></EditText>
<LinearLayout
Android:orientation="horizontal"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
<TextView
Android:id="@+id/txtDate"
Android:layout_width="wrap_content"
Android:text=""
Android:textSize="20dip"
Android:textColor="?textColorDark"
Android:layout_marginLeft="10dip"
Android:layout_height="@dimen/editTextHeight"
Android:layout_gravity="center_vertical" />
<Button
Android:id="@+id/btnPickDate"
Android:layout_width="wrap_content"
Android:layout_height="@dimen/editTextHeight"
Android:text="Select date"
Android:layout_margin="2dip"
Android:textSize="15dip"
Android:layout_gravity="center_vertical" />
</LinearLayout>
<TabHost
Android:id="@+id/tabhost"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<LinearLayout
Android:id="@+id/linearLayout1"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical">
<TabWidget
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:id="@Android:id/tabs"></TabWidget>
<FrameLayout
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:id="@Android:id/tabcontent">
<ScrollView
Android:layout_above="@id/buttons"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:fillViewport="true"
Android:id="@+id/tab1">
<LinearLayout
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical">
<TableLayout
Android:layout_height="wrap_content"
Android:layout_width="fill_parent">
<TableRow
Android:id="@+id/tableRow1"
Android:layout_marginLeft="2dip"
Android:layout_marginRight="5dip"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
<LinearLayout
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<ImageView
Android:src="@drawable/ic_menu_invite"
Android:layout_width="40dip"
Android:layout_height="40dip"
Android:layout_gravity="center_vertical"></ImageView>
<TextView
Android:text="Add friend"
Android:layout_height="wrap_content"
Android:layout_width="fill_parent"
Android:layout_centerVertical="true"
Android:textColor="?textColorDark"
Android:textSize="@dimen/editText"
Android:layout_gravity="center_vertical" />
</LinearLayout>
</TableRow>
<TableRow
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_marginLeft="5dip"
Android:layout_marginRight="5dip">
<TextView
Android:id="@+id/txtData1"
Android:layout_width="170dip"
Android:layout_height="wrap_content"
Android:text="Data"
Android:textSize="14dip"
Android:textStyle="bold"
Android:textColor="#000000">
</TextView>
<TextView
Android:id="@+id/txtData2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Sample"
Android:textSize="13dip"
Android:textColor="#000000"></TextView>
</TableRow>
</TableLayout>
<ListView
Android:cacheColorHint="#00000000"
Android:id="@+id/ListView01"
Android:layout_height="wrap_content"
Android:layout_width="fill_parent" />
</LinearLayout>
</ScrollView>
<LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:gravity="center_horizontal"
Android:id="@+id/tab2"
Android:orientation="vertical">
<TableLayout
Android:layout_height="wrap_content"
Android:layout_width="fill_parent">
<TableRow
Android:id="@+id/tableRow2"
Android:layout_marginLeft="2dip"
Android:layout_marginRight="5dip"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
<LinearLayout
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<ImageView
Android:src="@drawable/ic_menu_invite"
Android:layout_width="40dip"
Android:layout_height="40dip"
Android:layout_gravity="center_vertical"></ImageView>
<TextView
Android:text="Sample"
Android:layout_height="wrap_content"
Android:layout_width="fill_parent"
Android:layout_centerVertical="true"
Android:textColor="?textColorDark"
Android:textSize="@dimen/editText"
Android:layout_gravity="center_vertical" />
</LinearLayout>
</TableRow>
<TableRow
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_marginLeft="5dip"
Android:layout_marginRight="5dip">
<TextView
Android:id="@+id/txtUser1"
Android:layout_width="170dip"
Android:layout_height="wrap_content"
Android:text="User"
Android:textSize="14dip"
Android:textStyle="bold"
Android:textColor="#000000">
</TextView>
<TextView
Android:id="@+id/txtUserData"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="UserData"
Android:textSize="13dip"
Android:textColor="#000000"></TextView>
</TableRow>
</TableLayout>
<ListView
Android:cacheColorHint="#00000000"
Android:id="@+id/ListView02"
Android:layout_height="wrap_content"
Android:layout_width="fill_parent" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>
</ScrollView>
</RelativeLayout>
S'il vous plaît quelqu'un peut-il me dire quel est le problème ici? J'ai un autre message sur la liste dans le problème de ScrollView, mais ils n'étaient d'aucune utilité dans mon cas.
Vous ne devez pas placer une ListView
dans une ScrollView
car la classe ListView
implémente son propre défilement et ne reçoit tout simplement pas de gestes, car ils sont tous gérés par le parent ScrollView
. Je vous recommande fortement de simplifier votre mise en page. Par exemple, vous pouvez ajouter des vues que vous souhaitez faire défiler jusqu'à la ListView
en tant qu'en-têtes ou pieds de page.
METTRE &AGRAVE; JOUR:
À partir de l'API niveau 21 (Lollipop), les conteneurs de défilement imbriqués sont officiellement pris en charge par le SDK Android. Il existe de nombreuses méthodes dans les classes View
et ViewGroup
qui fournissent cette fonctionnalité. Pour que le défilement imbriqué fonctionne sur Lollipop, vous devez l'activer pour une vue de défilement enfant en ajoutant Android:nestedScrollingEnabled="true"
à sa déclaration XML ou en appelant explicitement setNestedScrollingEnabled(true)
.
Si vous voulez que le défilement imbriqué fonctionne sur les périphériques antérieurs à Lollipop, ce que vous faites probablement, vous devez utiliser les classes d’utilitaires correspondantes de la bibliothèque Support. Vous devez d’abord vous remplacer ScrollView
par NestedScrollView . Ce dernier implémente à la fois NestedScrollingParent et NestedScrollingChild afin qu'il puisse être utilisé en tant que conteneur parent ou défilement enfant.
Mais ListView
ne prend pas en charge le défilement imbriqué, vous devez donc le sous-classer et mettre en œuvre NestedScrollingChild
. Heureusement, la bibliothèque de support fournit NestedScrollingChildHelper class. Il vous suffit donc de créer une instance de cette classe et d’appeler ses méthodes à partir des méthodes correspondantes de votre classe de vue.
J'ai trouvé une solution qui fonctionne parfaitement et qui permet de faire défiler la ListView
sans problème:
ListView lv = (ListView)findViewById(R.id.myListView); // your listview inside scrollview
lv.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;
}
});
Cela permet de désactiver les TouchEvent
s sur ScrollView
et de les intercepter par ListView
. C'est simple et ça marche tout le temps.
J'ai aussi une solution. J'utilise toujours cette méthode. Essaye ça
<ScrollView
Android:id="@+id/createdrill_scrollView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" >
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginLeft="20dp"
Android:layout_marginRight="20dp"
Android:layout_marginTop="15dp" >
<net.thepaksoft.fdtrainer.NestedListView
Android:id="@+id/crewList"
Android:layout_width="0dip"
Android:layout_height="wrap_content"
Android:layout_marginBottom="2dp"
Android:layout_weight="1"
Android:background="@drawable/round_shape"
Android:cacheColorHint="#00000000" >
</net.thepaksoft.fdtrainer.NestedListView>
</LinearLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginLeft="20dp"
Android:layout_marginRight="20dp"
Android:layout_marginTop="15dp" >
<net.thepaksoft.fdtrainer.NestedListView
Android:id="@+id/benchmarksList"
Android:layout_width="0dip"
Android:layout_height="wrap_content"
Android:layout_marginBottom="2dp"
Android:layout_weight="1"
Android:background="@drawable/round_shape"
Android:cacheColorHint="#00000000" >
</net.thepaksoft.fdtrainer.NestedListView>
</LinearLayout>
</ScrollView>
Classe NestedListView.Java:
public class NestedListView extends ListView implements OnTouchListener, 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;
}
}
Vous devez simplement remplacer votre <ScrollView ></ScrollView>
par ce Custom ScrollView
comme <com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >
package com.tmd.utils;
import Android.content.Context;
import Android.util.AttributeSet;
import Android.util.Log;
import Android.view.MotionEvent;
import Android.widget.ScrollView;
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false" );
return false;
default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action ); break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
J'ai eu le même problème et en cherchant sur Google, j'ai trouvé votre question. Oui, la réponse marquée a fonctionné pour moi aussi, mais il y avait un problème.
Quoi qu'il en soit, j'ai trouvé une autre solution . qui fonctionne parfaitement sans jongler.
list.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;
}
});
Voici la méthode exacte d’utilisation de Listview dans la Scrollview. Tout ce que nous devons gérer les événements tactiles.
lstvNextTracks.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
Log.e("Lisview *************", "focused");
SCView.requestDisallowInterceptTouchEvent(true);
return false;
}
});
SCView.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
int arr[] = new int[] { 1, 2 };
lstvNextTracks.getLocationOnScreen(arr);
/* Get bounds of child Listview*/
int lstvTop = arr[0];
int lstvBottom = arr[1] + lstvNextTracks.getHeight();
int lstvLeft = arr[1];
int lstvRight = arr[0] + lstvNextTracks.getWidth();
float x = event.getRawX();
float y = event.getRawY();
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
/*check if child ListView bounds are touched*/
if (x > lstvTop && x < lstvBottom && y > lstvLeft && y < lstvRight)
{
SCView.clearFocus();
/*This statement tells the ScrollView to do not handle this touch event, so the child Listview will handle this touch event and will scroll */
SCView.requestDisallowInterceptTouchEvent(true);
/*The child Listview isFocusable attribute must be set to true otherwise it will not work*/
lstvNextTracks.requestFocus();
return true;
} else
return false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE)
{
if (x > lstvTop && x < lstvBottom && y > lstvLeft && y < lstvRight)
{
SCView.clearFocus();
SCView.requestDisallowInterceptTouchEvent(true);
lstvNextTracks.requestFocus();
return true;
} else
return false;
} else if (event.getAction() == MotionEvent.ACTION_UP)
{
SCView.clearFocus();
SCView.requestDisallowInterceptTouchEvent(true);
lstvNextTracks.requestFocus();
return false;
} else
{
return false;
}
}
});
Utilisez la méthode suivante et profitez-en!
private void setListViewScrollable(final ListView list) {
list.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
listViewTouchAction = event.getAction();
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
list.scrollBy(0, 1);
}
return false;
}
});
list.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
list.scrollBy(0, -1);
}
}
});
}
listViewTouchAction est une valeur entière globale . Si vous pouvez remplacer la ligne
list.scrollBy(0, 1);
avec quelque chose d'autre s'il vous plaît partagez-le avec nous.
Prendre plaisir!
C'est une mauvaise pratique d'avoir deux vues de défilement différentes ensemble. ListView lui-même dispose de sa propre fonctionnalité de défilement et la hauteur est ajustée automatiquement en fonction des paramètres de l’adaptateur pour vos éléments de ligne (Keelping en tête, nous ne définissons pas de hauteur spécifique pour ListView dans notre Layout xml). Cependant, dans votre cas, vous pouvez remplacer ListView par une classe, ce qui ajustera la hauteur de votre ListView en gardant à l'esprit que votre ListView se trouve dans ScrollView.
Cela vous aidera
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;
}
}
Maintenant, étendez votre ListView avec cette classe, il suffit de changer votre balise ListView de votre ressource xml pour qu'elle ressemble à celle-ci,
<yourpackagename.ExpandableHeightListview
Android:id="@+id/listView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@color/White"
Android:scrollbars="none"
Android:orientation="vertical"
Android:fadingEdge="none">
</cyourpackagename.ExpandableHeightListview>
Cela résoudra votre problème de défilement de ListView, car le défilement parent est maintenant géré par ScrollView plutôt que par ListView.
J'ai un problème similaire et résolu en créant une classe personnalisée en étendant avec ListView.
ScrollableListView.Java
import Android.content.Context;
import Android.util.AttributeSet;
import Android.widget.ListView;
public class ScrollableListView extends ListView {
public ScrollableListView (Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollableListView (Context context) {
super(context);
}
public ScrollableListView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Utilisation:
<com.my.package.ScrollableListView
Android:id="@+id/listview"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"/>
J'ai essayé et testé presque toutes les méthodes mentionnées ci-dessus, faites-moi confiance, après avoir complètement fui RecyclerView, j'ai remplacé mon ListView par RecyclerView et tout fonctionnait parfaitement. N'avait besoin d'aucune bibliothèque tierce partie pour ExtendedHeightListView et tout simplement RecyclerView.
Alors, voici mon fichier de mise en page avant recyclerView:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/scrollView"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:elevation="5dp">
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/relativeLayoutre"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="2dp"
tools:context="com.example.Android.udamovappv3.activities.DetailedActivity">
<Android.support.v7.widget.Toolbar
Android:id="@+id/my_toolbar_detail"
Android:layout_width="match_parent"
Android:layout_height="56dp"
Android:layout_gravity="top"
Android:background="?attr/colorPrimary"
Android:elevation="4dp"
Android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<TextView
Android:id="@+id/title_name"
Android:layout_width="fill_parent"
Android:layout_height="128dp"
Android:layout_alignParentStart="true"
Android:layout_marginTop="59dp"
Android:background="#079ED9"
Android:gravity="left|center"
Android:padding="25dp"
Android:text="Name"
Android:textColor="#ffffff"
Android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/my_toolbar_detail"
app:layout_constraintVertical_bias="0.0"
tools:layout_editor_absoluteX="0dp" />
<ImageView
Android:id="@+id/iv_poster"
Android:layout_width="131dp"
Android:layout_height="163dp"
Android:layout_alignStart="@+id/my_toolbar_detail"
Android:layout_below="@+id/title_name"
Android:layout_marginBottom="15dp"
Android:layout_marginRight="8dp"
Android:layout_marginTop="15dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="@mipmap/ic_launcher" />
<Button
Android:id="@+id/bt_mark_as_fav"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignBottom="@+id/iv_poster"
Android:layout_alignParentEnd="true"
Android:layout_marginBottom="11dp"
Android:layout_marginEnd="50dp"
Android:background="#079ED9"
Android:text="Mark As \n Favorite"
Android:textSize="10dp" />
<TextView
Android:id="@+id/tv_runTime"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignStart="@+id/tv_rating"
Android:layout_below="@+id/tv_releaseDate"
Android:layout_marginTop="11dp"
Android:text="TextView"
Android:textSize="20sp" />
<TextView
Android:id="@+id/tv_releaseDate"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignStart="@+id/tv_runTime"
Android:layout_alignTop="@+id/iv_poster"
Android:text="TextView"
Android:textSize="25dp" />
<TextView
Android:id="@+id/tv_rating"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignStart="@+id/bt_mark_as_fav"
Android:layout_below="@+id/tv_runTime"
Android:layout_marginTop="11dp"
Android:text="TextView" />
<TextView
Android:id="@+id/tv_overview"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_below="@+id/iv_poster"
Android:layout_centerHorizontal="true"
Android:layout_marginBottom="5dp"
Android:foregroundGravity="center"
Android:text="adasdasdfadfsasdfasdfasdfasdfnb agfjuanfalsbdfjbdfklbdnfkjasbnf;kasbdnf;kbdfas;kdjabnf;lbdnfo;aidsnfl';asdfj'plasdfj'pdaskjf'asfj'p[asdfk"
Android:textColor="#000000"
/>
<RelativeLayout
Android:id="@+id/foodItemActvity_linearLayout_fragments"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:layout_below="@+id/tv_overview">
<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" />
<com.github.paolorotolo.expandableheightlistview.ExpandableHeightListView
Android:id="@+id/expandable_listview"
Android:layout_width="fill_parent"
Android:layout_height="match_parent"
Android:layout_alignParentBottom="true"
Android:layout_alignParentStart="true"
Android:layout_below="@+id/fragment_dds_review_textView_label"
Android:padding="8dp">
</com.github.paolorotolo.expandableheightlistview.ExpandableHeightListView>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
CECI IS APRÈS REMPLACER MON LISTVIEW PAR L’UNE DES PLUS GRANDES SOLUTIONS MENTIONÉES CI-DESSUS. Donc le problème était que la listview ne se comportait pas correctement à cause du bogue 2 scrollview (peut-être pas un bogue) dans Android.
J'ai remplacé le Avec recycler vue pour former ma mise en page finale.
Ceci est mon adaptateur de vue recycleur:
public class TrailerAdapter extends RecyclerView.Adapter<TrailerAdapter.TrailerAdapterViewHolder> {
private ArrayList<String> Youtube_URLS;
private Context Context;
public TrailerAdapter(Context context, ArrayList<String> Youtube_URLS){
this.Context = context;
this.Youtube_URLS = Youtube_URLS;
}
@Override
public TrailerAdapter.TrailerAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.trailer_layout, parent, false);
return new TrailerAdapterViewHolder(view);
}
@Override
public void onBindViewHolder(TrailerAdapter.TrailerAdapterViewHolder holder, int position) {
Picasso.with(Context).load(R.drawable.ic_play_arrow_black_24dp).into(holder.iv_playbutton);
holder.item_id.setText(Youtube_URLS.get(position));
}
@Override
public int getItemCount() {
if(Youtube_URLS.size()==0){
return 0;
}else{
return Youtube_URLS.size();
}
}
public class TrailerAdapterViewHolder extends RecyclerView.ViewHolder {
ImageView iv_playbutton;
TextView item_id;
public TrailerAdapterViewHolder(View itemView) {
super(itemView);
iv_playbutton = (ImageView)itemView.findViewById(R.id.play_button);
item_id = (TextView)itemView.findViewById(R.id.tv_trailer_sequence);
}
}
}
Et voici ma mise en page personnalisée RecyclerView:
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="56dp"
Android:padding="6dip" >
<ImageView
Android:id="@+id/play_button"
Android:layout_width="70dp"
Android:layout_height="wrap_content"
Android:layout_marginRight="6dip"
Android:layout_marginStart="12dp"
Android:src="@drawable/ic_play_arrow_black_24dp"
Android:layout_centerVertical="true"
Android:layout_alignParentStart="true" />
<TextView
Android:id="@+id/tv_trailer_sequence"
Android:layout_width="wrap_content"
Android:layout_height="26dip"
Android:layout_centerVertical="true"
Android:layout_toEndOf="@+id/play_button"
Android:ellipsize="Marquee"
Android:gravity="center"
Android:maxLines="1"
Android:text="Description"
Android:textSize="12sp" />
</RelativeLayout>
Et VOILA, l’effet souhaité de ListView (Now RecyclerView) au sein d’un scollview. Voici l'image finale de l'interface utilisateur
Pour terminer, je pense que le remplacement de RecyclerView était un meilleur choix pour moi, car il améliorait la stabilité globale de l'application et me permettait également de mieux comprendre RecyclerView. Si je devais proposer une solution, je vais dire de remplacer votre ListView par un RecyclerView.
Je sais que cette question est posée depuis longtemps, mais celui qui est bloqué pour le moment peut résoudre ce problème en ajoutant cette ligne à votre liste.
Android:nestedScrollingEnabled="true"
Par exemple -
<ListView
Android:id="@+id/listView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:nestedScrollingEnabled="true" />
La solution ci-dessus donnée par @Shailesh Rohit fonctionne parfaitement bien. Quelques astuces doivent être faites.
Si vous placez la classe helper dans la même classe (classe principale), définissez Helper class en tant que statique et getListViewSize () n'est pas statique.
Le plus important, écrivez "Helper.getListViewSize (listView);" instruction après la définition de l'adaptateur pour la première fois comme "listView.setAdapter (myAdapter);" ainsi que chaque fois que vous utilisez "myAdapter.notifyDataSetChanged ();"
L'utilisation est indiquée ci-dessous.
listView = (ListView) findViewById (R.id.listView); myAdapter = new ArrayAdapter (cela, Android.R.layout.simple_list_item_1, listValues); listView .setAdapter (myAdapter); Helper. getListViewSizelistView (listView);
monAdaptateur.notifyDataSetChanged (); Helper.getListViewSizelistView (listView);
La meilleure solution consiste à utiliser NestedScrollVew avec RecyclerView ou si vous souhaitez utiliser Listview, vous pouvez ajouter une vue d'en-tête et de pied de page à cette .
View footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.outofoffice_footer_view, null, false);
infoListView.addFooterView(footerView);
Demo_ListView_In_ScrollView
==============================
package com.app.custom_seekbar;
import Java.util.ArrayList;
import Android.app.Activity;
import Android.os.Bundle;
import Android.widget.ListView;
public class Demo_ListView_In_ScrollView extends Activity
{
ListView listview;
ArrayList<String> data=null;
listview_adapter adapter=null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
super.setContentView(R.layout.demo_listview_in_scrollview_activity);
init();
set_data();
set_adapter();
}
public void init()
{
listview=(ListView)findViewById(R.id.listView1);
data=new ArrayList<String>();
}
public void set_data()
{
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
data.add("Meet");
data.add("prachi");
data.add("shailesh");
data.add("manoj");
data.add("sandip");
data.add("zala");
data.add("tushar");
}
public void set_adapter()
{
adapter=new listview_adapter(Demo_ListView_In_ScrollView.this,data);
listview.setAdapter(adapter);
Helper.getListViewSize(listview); // set height of listview according to Arraylist item
}
}
=========================
listview_adapter
==========================
package com.app.custom_seekbar;
import Java.util.ArrayList;
import Android.app.Activity;
import Android.view.LayoutInflater;
import Android.view.MotionEvent;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ArrayAdapter;
import Android.widget.LinearLayout;
import Android.widget.ScrollView;
import Android.widget.TextView;
public class listview_adapter extends ArrayAdapter<String>
{
private final Activity context;
ArrayList<String>data;
class ViewHolder
{
public TextView tv_name;
public ScrollView scroll;
public LinearLayout l1;
}
public listview_adapter(Activity context, ArrayList<String> all_data) {
super(context, R.layout.item_list_xml, all_data);
this.context = context;
data=all_data;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder viewHolder;
if (rowView == null)
{
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.item_list_xml, null);
viewHolder = new ViewHolder();
viewHolder.tv_name=(TextView)rowView.findViewById(R.id.textView1);
rowView.setTag(viewHolder);
}
else
viewHolder = (ViewHolder) rowView.getTag();
viewHolder.tv_name.setText(data.get(position).toString());
return rowView;
}
}
===================================
Classe d'assistance
====================================
import Android.util.Log;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ListAdapter;
import Android.widget.ListView;
public class Helper {
public static void getListViewSize(ListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null) {
//do nothing return null
return;
}
//set listAdapter in loop for getting final size
int totalHeight = 0;
for (int size = 0; size < myListAdapter.getCount(); size++) {
View listItem = myListAdapter.getView(size, null, myListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
//setting listview item in adapter
ViewGroup.LayoutParams params = myListView.getLayoutParams();
params.height = totalHeight + (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));
myListView.setLayoutParams(params);
// print height of adapter on log
Log.i("height of listItem:", String.valueOf(totalHeight));
}
}
=========================
demo_listview_in_scrollview_activity.xml
=========================
<?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="match_parent"
Android:orientation="vertical" >
<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<ListView
Android:id="@+id/listView1"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
</ScrollView>
</LinearLayout>
================
item_list_xml.xml
===================
<?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="match_parent"
Android:orientation="vertical" >
<TextView
Android:id="@+id/textView1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center_horizontal"
Android:gravity="center"
Android:text="TextView"
Android:textSize="14sp" />
</LinearLayout>
Ajouter: Android:nestedScrollingEnabled="true"
Essayez ceci avec ScrollView, pas avec ListView.
public class xScrollView extends ScrollView
{
;
;
@Override
public boolean onInterceptTouchEvent (MotionEvent ev)
{
return false;
}
}
Appelée lorsqu'un enfant ne veut pas que ce parent et ses ancêtres interceptent les événements tactiles avec onInterceptTouchEvent (MotionEvent) . Ce parent devrait passer cet appel à ses parents. Ce parent doit obéir à cette demande pendant toute la durée du contact (c’est-à-dire qu’il n’efface le drapeau que lorsque ce parent a reçu une hausse ou une annulation.
Essayez cette réponse,
listview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of child view
scrollView.requestDisallowInterceptTouchEvent(true);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_UP:
scrollView.requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
});
Comme Selon moi, lorsque vous utilisez setOnTouchListener, un parent ou un enfant arrête le défilement du parent lorsque vous touchez l’enfant.
Remplacez ScrollView par Android.support.v4.widget.NestedScrollView dans XML. ça court
1) Utilisation en XML :::: Android.support.v4.widget.NestedScrollView
au lieu de :::: ScrollView
2) Et utilisez la vue liste de cette manière en utilisant NonScrollListView dans le fichier cs:
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();
}
}
3) Enfin, utilisez ce code pour identifier scrollview dans le fichier cs:
NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
Utilisez cette méthode et votre listview devient défilable dans scrollview: -
ListView lstNewsOffer.setAdapter(new ViewOfferAdapter(
ViewNewsDetail.this, viewOfferList));
getListViewSize(lstNewsOffer);
void getListViewSize(ListView myListView) {
ListAdapter myListAdapter = myListView.getAdapter();
if (myListAdapter == null) {
// do nothing return null
return;
}
// set listAdapter in loop for getting final size
int totalHeight = 0;
for (int size = 0; size < myListAdapter.getCount(); size++) {
View listItem = myListAdapter.getView(size, null, myListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
// setting listview item in adapter
ViewGroup.LayoutParams params = myListView.getLayoutParams();
params.height = totalHeight
+ (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));
myListView.setLayoutParams(params);
// print height of adapter on log
Log.i("height of listItem:", String.valueOf(totalHeight));
}
remplacez ListView par RecycleView dans ScrollView. il fonctionne bien sans code source supplémentaire:
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.hung.recycleviewtest.MainActivityFragment"
>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycle_view"
Android:layout_width="match_parent"
Android:layout_height="400dp"
Android:background="@Android:color/darker_gray"/>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycle_view_a"
Android:layout_marginTop="40dp"
Android:layout_below="@id/recycle_view"
Android:layout_width="match_parent"
Android:layout_height="400dp"
Android:background="@Android:color/darker_gray"/>
</RelativeLayout>
</ScrollView>
J'ai eu cette erreur.Et ma solution est la suivante:
1. Créer une liste personnalisée qui ne peut pas défiler
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. Utiliser la classe personnalisée ci-dessus pour un fichier xml
<com.Example.NonScrollListView
Android:id="@+id/lv_nonscroll_list"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
J'espère le mieux pour vous.
Meilleur code
<Android.support.v4.widget.NestedScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_above="@+id/btmlyt"
Android:layout_below="@+id/deshead_tv">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
>
<TextView
Android:id="@+id/des_tv"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_above="@+id/btmlyt"
Android:background="@Android:color/white"
Android:paddingLeft="3dp"
Android:paddingRight="3dp"
Android:scrollbars="vertical"
Android:paddingTop="3dp"
Android:text="description"
Android:textColor="@Android:color/black"
Android:textSize="18sp" />
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
J'ai trouvé une solution pour cela, Au lieu d'utiliser scrollview, vous pouvez utiliser addHeaderview et addFooterview of listview
Voici mon extrait,
// create separate layout and add it dynamically
scrollview=getLayoutInflater().inflate(R.layout.yourlayout,null);
lv=(ListView)listview.findViewById(R.id.listView2);
lv.addHeaderView(scrollview);
lv.setContentView(lv);
Maintenant, avec la listview, vous pouvez également faire défiler votre disposition. Profitez-en!!!
Pour ListView dans ScrollView, utilisez NestedScrollView, il peut gérer très facilement cette fonctionnalité
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:padding="5dip"/>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>