ListView внутри ScrollView не прокручивается на Android
У меня возникают проблемы с прокруткой ListView
внутри ScrollView
. У меня есть Activity, у которого есть некоторые EditTexts в верхней части, а затем на вкладке с двумя вкладками, которые имеют один ListView каждый. Когда виды EditText сфокусированы, появляется мягкая клавиатура, и, поскольку у меня есть ScrollView, содержимое прокручивается. Но проблема возникает, когда в ListViews больше элементов (в вкладках), я не могу прокручивать ListView, даже если есть больше элементов.
Ниже представлен формат XML:
<?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>
Пожалуйста, кто-нибудь скажет мне, в чем проблема? У меня есть другая запись в ListView внутри задачи ScrollView, но они бесполезны в моем случае.
Ответы
Ответ 1
Вы не должны помещать ListView
внутри ScrollView
, потому что класс ListView
реализует свою собственную прокрутку, и он просто не принимает жесты, потому что все они обрабатываются родительским ScrollView
. Я настоятельно рекомендую вам как-то упростить ваш макет. Например, вы можете добавлять просмотры, которые вы хотите прокрутить, к ListView
в виде верхних и нижних колонтитулов.
UPDATE
Начиная с API уровня 21 (Lollipop) вложенные контейнеры прокрутки официально поддерживаются Android SDK. В классах View
и ViewGroup
есть набор методов, которые предоставляют эту функцию. Чтобы сделать вложенную прокрутку на Lollipop, вы должны включить ее для просмотра детальной прокрутки, добавив android:nestedScrollingEnabled="true"
в свое объявление XML или явно вызывая setNestedScrollingEnabled(true)
.
Если вы хотите, чтобы вложенная прокрутка работала на устройствах pre-Lollipop, что вы, вероятно, делаете, вам нужно использовать соответствующие классы утилиты из библиотеки поддержки. Сначала вам нужно заменить ScrollView
на NestedScrollView. Последний реализует NestedScrollingParent и NestedScrollingChild, поэтому его можно использовать в качестве родительского или дочернего контейнера прокрутки.
Но ListView
не поддерживает вложенную прокрутку, поэтому вам нужно подклассифицировать его и реализовать NestedScrollingChild
. К счастью, библиотека поддержки предоставляет NestedScrollingChildHelper класс, поэтому вам просто нужно создать экземпляр этого класса и вызвать его методы из соответствующих методов ваш класс просмотра.
Ответ 2
Я нашел решение, которое отлично работает и может без проблем прокручивать ListView
:
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;
}
});
Что это значит - отключить TouchEvent
на ScrollView
и сделать ListView
перехватить их. Это просто и работает все время.
Ответ 3
У меня также есть одно решение. Я всегда использую этот метод. Попробуйте это
<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>
Класс 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;
}
}
Ответ 4
Вам нужно просто заменить <ScrollView ></ScrollView>
на Custom ScrollView
как <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;
}
}
Ответ 5
У меня была такая же проблема, и в то время, когда я искал Google, я нашел ваш вопрос. Да, заметный ответ тоже работал у меня, но была проблема. В любом случае я нашел другое решение.
который отлично работает без каких-либо фокусов.
Ответ 6
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;
}
});
Ответ 7
Используйте следующий метод и наслаждайтесь!
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 - это глобальное целочисленное значение.
Если вы можете заменить строку
list.scrollBy(0, 1);
с чем-то другим, пожалуйста, поделитесь им с нами.
Наслаждайтесь!
Ответ 8
Вот точный метод использования Listview с в Scrollview. Все, что нам нужно для обработки сенсорных событий.
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;
}
}
});
Ответ 9
Плохая практика состоит в том, чтобы иметь два разных скроллинга. В ListView есть свои собственные функции прокрутки, и высота автоматически настраивается в соответствии с настройками адаптера для ваших элементов строки (учитывая, что мы не устанавливаем определенную высоту в ListView в нашем макете xml). Однако в вашем случае вы можете заменить ListView классом, и это позволит настроить высоту для вашего ListView, имея в виду, что ListView находится внутри ScrollView.
Это поможет вам:
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;
}
}
Теперь расширьте ListView этим классом, просто измените свой тег ListView с вашего ресурса xml на такое, как это,
<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>
Это решит вашу проблему прокрутки ListView, так как теперь родительская прокрутка управляется ScrollView, а не ListView.
Ответ 10
У меня есть аналогичная проблема и разрешена путем создания пользовательского класса путем расширения с помощью 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);
}
}
Применение:
<com.my.package.ScrollableListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Ответ 11
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;
}
}
===================================
Класс помощника
====================================
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>
Ответ 12
Лучшим решением является использование NestedScrollVew с RecyclerView или если вы хотите перейти с Listview, то вы можете добавить в него представление верхнего и нижнего колонтитула.
Например:
View footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.outofoffice_footer_view, null, false);
infoListView.addFooterView(footerView);
Ответ 13
Я пробовал и тестировал почти все упомянутые выше методы, поверьте мне, после того, как полностью убежал от RecyclerView, я заменил свой ListView на RecyclerView, и он отлично работал. Не нужна какая-либо сторонняя библиотека для ExtendedHeightListView и все, просто и просто RecyclerView.
Итак, Heres my Layout файл перед 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>
ЭТО ПОСЛЕ ЗАМЕНЫ МОЕЙ ЛИСИСТИКИ С ОДНИМ ИЗ МНОГО РЕШЕНИЙ, УКАЗАННЫХ ВЫШЕ. Поэтому проблема заключалась в том, что listview не вел себя должным образом из-за ошибки 2 scrollview (возможно, не ошибки) в android.
Я заменил
с видом recycler, чтобы сформировать форму моего окончательного макета.
Это адаптер адаптера recycler:
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);
}
}
}
И это мой пользовательский макет 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>
И VOILA, я получил желаемый эффект ListView (Now RecyclerView) в scollview.
Получает окончательное изображение пользовательского интерфейса
В заключение я считаю, что замена RecyclerView была для меня лучшим выбором, так как она улучшила общую стабильность приложения, а также помогла мне лучше понять RecyclerView. Если бы я предложил предложить решение, я скажу, что замените ListView на RecyclerView.
Ответ 14
Выше решение, данное @Shailesh Rohit, отлично работает. Некоторые трюки должны быть выполнены.
-
Если вы помещаете вспомогательный класс внутри одного класса (основной класс), тогда создайте класс Helper как static, а getListViewSize() не будет статическим.
-
Самое главное, напишите "Helper.getListViewSize(listView)"; утверждение после установки адаптера в первый раз, например "listView.setAdapter(myAdapter)"; а также когда вы используете "myAdapter.notifyDataSetChanged();"
-
Использование показано ниже.
listView = (ListView) findViewById (R.id.listView);
myAdapter = новый ArrayAdapter (это, android.R.layout.simple_list_item_1, listValues);
listView.setAdapter(myAdapter);
Helper.getListViewSizelistView(ListView);
myAdapter.notifyDataSetChanged();
Helper.getListViewSizelistView(ListView);
Ответ 15
Я знаю, что этот вопрос задан давно, но кто когда-либо застрял, теперь может решить эту проблему, добавив эту строку в список ListView
android:nestedScrollingEnabled="true"
Например -
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true" />
Ответ 16
Как мне известно, когда вы используете setOnTouchListener om parent или child, прекратите прокрутку родительского элемента, когда вы касаетесь другого ребенка, прекратите прокрутку дочернего элемента, когда вы касаетесь родительского
Ответ 17
Используйте этот метод, и ваш список будет прокручиваться внутри 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));
}
Ответ 18
Попробуйте это с помощью ScrollView, а не с ListView.
public class xScrollView extends ScrollView
{
;
;
@Override
public boolean onInterceptTouchEvent (MotionEvent ev)
{
return false;
}
}
Ответ 19
requestDisallowInterceptTouchEvent (boolean disallowIntercept)
Вызывается, когда ребенок не хочет, чтобы этот родитель и его предки перехватывали события касания с помощью onInterceptTouchEvent (MotionEvent). Этот родитель должен передать этот звонок своим родителям. Этот родитель должен подчиняться этому запросу на время касания (то есть только очистить флаг после того, как этот родитель получил сообщение "вверх" или "отмена".
Попробуйте этот ответ,
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;
}
});
Ответ 20
заменить ListView на RecycleView внутри ScrollView. он работает без дополнительного исходного кода:
<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>
Ответ 21
Для ListView внутри ScrollView используйте NestedScrollView, он может обрабатывать этот
функциональность очень легко:
<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>
Ответ 22
У меня была эта ошибка. И мое решение следующее:
1. Создайте пользовательский список, который не прокручивается
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. Использовать над пользовательским классом для xml файла
<com.Example.NonScrollListView
android:id="@+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
Надеюсь, что лучше для вас.
Ответ 23
Я нашел решение для этого,
Вместо использования scrollview вы можете использовать addHeaderview и addFooterview of listview
Вот мой фрагмент,
// 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);
Теперь с помощью списка можно также прокручивать макет. Наслаждайтесь этим!
Ответ 24
Замените ScrollView на android.support.v4.widget.NestedScrollView внутри xml. он работает
1) Использовать в XML :: android.support.v4.widget.NestedScrollView
вместо :: ScrollView
2) И используйте для просмотра списка таким образом, используя NonScrollListView в файле 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) Наконец, используйте этот код для идентификации scrollview в файле cs:
NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
Ответ 25
Лучший код
<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>
Ответ 26
Добавить: android:nestedScrollingEnabled="true"
Ответ 27
Не показывайте прокрутку до ListView
, поскольку он имеет этот параметр по умолчанию
<ListView
android:cacheColorHint="#00000000"
android:id="@+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
Ответ 28
Вы не можете добавить ListView в прокрутку View, так как просмотр списка также scolls и возникнет проблема синхронизации между прокруткой списка и scroll view scoll.
Вы можете сделать CustomList View и добавить в него этот метод.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* Prevent parent controls from stealing our events once we've gotten a touch down
*/
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
ViewParent p = getParent();
if (p != null) {
p.requestDisallowInterceptTouchEvent(true);
}
}
return false;
}