목록 보기를 축소하지 않고 스크롤 보기에 넣을 수 있는 방법은 무엇입니까?
이 문제에 대한 해결책을 찾아봤지만, 찾을 수 있는 유일한 답은 "목록 보기를 스크롤 뷰에 넣지 마세요"인 것 같습니다.그 이유에 대해서는 아직 정확한 설명이 없습니다.내가 찾을 수 있는 유일한 이유는 구글이 당신이 그렇게 하고 싶어하지 않는다고 생각하기 때문입니다.그래요, 그래서 그랬어요.
그러면 문제는 목록 보기를 최소 높이로 접지 않고 스크롤 보기에 배치할 수 있는 방법입니다.
이것이 제 해결책입니다.저는 안드로이드 플랫폼을 처음 접하는 사람인데, 특히 .measure를 직접 호출하고 설정하는 부분에서는 이것이 약간 해킹적이라고 확신합니다.LayoutParams.height
직접적인 재산이지만 효과가 있습니다.
할 은 ㅇㅇㅇㅇ에게 전화하는 것입니다.Utility.setListViewHeightBasedOnChildren(yourListView)
물건의 높이를 정확히 맞추기 위해 크기가 조정될 것입니다.
public class Utility {
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
}
A 을 합니다.ListView
그것을 스크롤하지 않게 하는 것은 매우 비싸고 전체 목적에 어긋납니다.ListView
. 그러면 안 됩니다.그냥 a로.LinearLayout
대신.
이것은 분명히 효과가 있을 것입니다......
당신은 그냥 당신의 것을 교체해야 합니다.<ScrollView ></ScrollView>
께웃 XML에서를 사용하여 레이아웃 파일에서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;
}
}
ㅇㅇ을 넣는 ListView
ScrollView
, 사용할수 있습니다ListView
ScrollView
할 . 에 에 .ListView
안에 넣을 수 있습니다ListView
. 의 ListView
에을여을수다dof다nt수sregy및t에을을여roListView
으로. 가.ListView
스크롤하는 경험을 제공할 것입니다.
ListView가 ScrollView에 있는 것이 매우 합리적인 상황은 많습니다.
여기 더그 W의 제안에 근거한 코드가 있습니다.단편적으로 작동하고 메모리를 덜 사용합니다.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
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);
listView.requestLayout();
}
호출 setListView내장된 각 목록 보기의 높이BasedOnChildren(목록 보기)입니다.
ListView는 실제로 이미 모든 항목을 표시할 수 있을 정도로 높이를 측정할 수 있지만 wrap_content(MeasureSpec)만 지정하면 이렇게 되지 않습니다.미지정).MeasureSpec으로 높이를 지정하면 이 작업을 수행합니다.AT_MOST.이 지식을 활용하면 위에 게시된 솔루션보다 훨씬 효과적으로 이 문제를 해결할 수 있는 매우 간단한 하위 클래스를 만들 수 있습니다.이 하위 클래스에는 wrap_content를 사용해야 합니다.
public class ListViewForEmbeddingInScrollView extends ListView {
public ListViewForEmbeddingInScrollView(Context context) {
super(context);
}
public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 4, MeasureSpec.AT_MOST));
}
}
높이 MeasureSpec을 매우 큰 크기의 AT_MOST로 조작(Integer)MAX_VALUE >> 4)를 사용하면 ListView가 모든 하위 항목을 지정된(매우 큰) 높이까지 측정하고 그에 따라 높이를 설정합니다.
다음과 같은 몇 가지 이유로 다른 솔루션보다 더 효과적입니다.
- 모든 것을 올바르게 측정합니다(패딩, 디바이더).
- 측정 패스 중에 ListView를 측정합니다.
- #2로 인해 별도의 코드 없이 폭이나 항목 수 변경을 올바르게 처리합니다.
이렇게 하는 것은 SDK의 문서화되지 않은 동작에 의존하는 것이며, 이는 변경될 수 있습니다.반면에 listView에서 wrap_content가 실제로 작동하는 방식이며 현재 wrap_content 동작이 중단된 것일 뿐이라고 주장할 수도 있습니다.
나중에 동작이 변경될 수 있을지 걱정된다면 onMeasure 기능과 관련 기능을 ListView.java에서 자신의 서브클래스로 복사한 다음 onMeasure를 통한 AT_MOST 경로를 UNSPECIED용으로도 실행해야 합니다.
참고로, 적은 수의 목록 항목을 사용할 때는 이것이 완벽하게 유효한 방법이라고 생각합니다.선형 레이아웃과 비교하면 비효율적일 수 있지만 항목 수가 적을 경우 선형 레이아웃을 사용하는 것은 불필요한 최적화이므로 불필요한 복잡성이 됩니다.
내장된 설정이 있습니다.스크롤 뷰에서:
android:fillViewport="true"
자바에서는.
mScrollView.setFillViewport(true);
여기서 Romain Guy가 자세히 설명해 드립니다. http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
스크롤할 수 없는 사용자 지정 목록 보기를 만듭니다.
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();
}
}
레이아웃 리소스 파일에서
<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>
Java 파일에서
ListView 대신 사용자 지정 ListView의 개체를 만듭니다. NonScrollListView non_slist = (NonScrollListView) findViewById(R.id.lv _nonscroll_list);
우리는 두 개의 스크롤을 동시에 사용할 수 없었습니다.ListView의 전체 길이를 구하고 전체 높이로 ListView를 확장합니다.그러면 ScrollView에 직접 자식이 하나 있으므로 ScrollView에 ListView를 추가하거나 LinearLayout을 사용할 수 있습니다. copy setListView코드에서 Lv(HightBasedOnChildren) 메서드를 사용하고 목록 보기를 확장하면 목록 보기를 스크롤 보기 내부에서 사용할 수 있습니다.\nxml 파일을 저장합니다.
<?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:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#1D1D1D"
android:orientation="vertical"
android:scrollbars="none" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#1D1D1D"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="40dip"
android:background="#333"
android:gravity="center_vertical"
android:paddingLeft="8dip"
android:text="First ListView"
android:textColor="#C7C7C7"
android:textSize="20sp" />
<ListView
android:id="@+id/first_listview"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:divider="#00000000"
android:listSelector="#ff0000"
android:scrollbars="none" />
<TextView
android:layout_width="fill_parent"
android:layout_height="40dip"
android:background="#333"
android:gravity="center_vertical"
android:paddingLeft="8dip"
android:text="Second ListView"
android:textColor="#C7C7C7"
android:textSize="20sp" />
<ListView
android:id="@+id/secondList"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:divider="#00000000"
android:listSelector="#ffcc00"
android:scrollbars="none" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Activity 클래스의 Create method:
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_inside_scrollview);
ListView list_first=(ListView) findViewById(R.id.first_listview);
ListView list_second=(ListView) findViewById(R.id.secondList);
ArrayList<String> list=new ArrayList<String>();
for(int x=0;x<30;x++)
{
list.add("Item "+x);
}
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,list);
list_first.setAdapter(adapter);
setListViewHeightBasedOnChildren(list_first);
list_second.setAdapter(adapter);
setListViewHeightBasedOnChildren(list_second);
}
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);
}
이것이 저에게 유일하게 도움이 된 것입니다.
롤리팝 이후에는 사용할 수 있습니다.
yourtListView.setNestedScrollingEnabled(true);
그러면 이전 버전의 OS와 역호환이 필요한 경우 RecyclerView를 사용해야 하는 이 보기에 대해 중첩 스크롤을 활성화하거나 비활성화합니다.
ListView가 이미 ScrollView이기 때문에 ScrollView에 ListView를 넣으면 안 됩니다.그러면 스크롤 뷰를 스크롤 뷰에 넣는 것과 같습니다.
당신은 무엇을 이루고자 합니까?
이것은 Doug W, Good Guy Greg, Paul의 답변을 종합한 것입니다.사용자 지정 리스트뷰 어댑터 및 비표준 리스트 아이템과 함께 이를 사용하려고 할 때 필요한 모든 것이 필요하다는 것을 알았습니다. 그렇지 않으면 리스트뷰가 애플리케이션을 충돌시킵니다(Nex의 답변과 함께 충돌).
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup)
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
@DougW의 했습니다를 했습니다.Utility
C#(Xamarin에서 사용됨)로 변환합니다.다음은 목록에 있는 고정 높이 항목에 대해 정상 작동하며, 일부 항목만 표준 항목보다 조금 더 크면 대부분 정상이거나 최소한 시작이 좋을 것입니다.
// You will need to put this Utility class into a code file including various
// libraries, I found that I needed at least System, Linq, Android.Views and
// Android.Widget.
using System;
using System.Linq;
using Android.Views;
using Android.Widget;
namespace UtilityNamespace // whatever you like, obviously!
{
public class Utility
{
public static void setListViewHeightBasedOnChildren (ListView listView)
{
if (listView.Adapter == null) {
// pre-condition
return;
}
int totalHeight = listView.PaddingTop + listView.PaddingBottom;
for (int i = 0; i < listView.Count; i++) {
View listItem = listView.Adapter.GetView (i, null, listView);
if (listItem.GetType () == typeof(ViewGroup)) {
listItem.LayoutParameters = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
}
listItem.Measure (0, 0);
totalHeight += listItem.MeasuredHeight;
}
listView.LayoutParameters.Height = totalHeight + (listView.DividerHeight * (listView.Count - 1));
}
}
}
감사합니다 @DougW, 다른 사람 코드로 일해야 하는 상황에서 이로 인해 궁지에서 벗어났습니다. :-)
그것이 불가능하기 전에.그러나 새로운 Appcompat 라이브러리와 Design 라이브러리가 출시되면 이를 달성할 수 있습니다.
NestedScrollView https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html 을 사용하기만 하면 됩니다.
Listview에서 작동할지는 모르겠지만 RecyclerView에서는 작동합니다.
코드 조각:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.NestedScrollView>
저도 비슷한 문제가 있었어요.스크롤되지 않는 목록 보기를 표시하려고 했는데 매개 변수를 조작하는 것은 효과적이지만 비효율적이며 다른 장치에서 다르게 작동한다는 것을 발견했습니다.결과적으로, 이것은 매우 효율적으로 이를 수행하는 제 일정 코드의 일부입니다.
db = new dbhelper(this);
cursor = db.dbCursor();
int count = cursor.getCount();
if (count > 0)
{
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layoutId);
startManagingCursor(YOUR_CURSOR);
YOUR_ADAPTER(**or SimpleCursorAdapter **) adapter = new YOUR_ADAPTER(this,
R.layout.itemLayout, cursor, arrayOrWhatever, R.id.textViewId,
this.getApplication());
int i;
for (i = 0; i < count; i++){
View listItem = adapter.getView(i,null,null);
linearLayout.addView(listItem);
}
}
참고: 이것을 사용하는 경우,notifyDataSetChanged();
뷰가 다시 그려지지 않기 때문에 의도한 대로 작동하지 않습니다.이 필요하면 이렇게 .
adapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
removeAndRedrawViews();
}
});
ScrollView 내부에서 ListView를 사용할 경우 두 가지 문제가 발생합니다.
1 - ListView는 해당 어린이 높이까지 완전히 확장해야 합니다.이 ListView는 다음을 해결합니다.
public class ListViewExpanded extends ListView
{
public ListViewExpanded(Context context, AttributeSet attrs)
{
super(context, attrs);
setDividerHeight(0);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST));
}
}
분할자 높이는 0이어야 합니다. 대신 행에 패딩을 사용합니다.
2- ListView는 터치 이벤트를 소비하므로 ScrollView를 평소처럼 스크롤할 수 없습니다.이 ScrollView를 사용하면 다음 문제가 해결됩니다.
public class ScrollViewInterceptor extends ScrollView
{
float startY;
public ScrollViewInterceptor(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e)
{
onTouchEvent(e);
if (e.getAction() == MotionEvent.ACTION_DOWN) startY = e.getY();
return (e.getAction() == MotionEvent.ACTION_MOVE) && (Math.abs(startY - e.getY()) > 50);
}
}
이것이 내가 찾은 가장 좋은 방법입니다!
제가 사용하는 솔루션은 스크롤뷰의 모든 컨텐츠(리스트뷰 위와 아래에 있어야 하는 것)를 목록뷰의 헤더뷰와 바닥글뷰로 추가하는 것입니다.
이렇게 작동합니다. 또한 변환 뷰가 어떻게 되야 하는지 다시 표시됩니다.
Vinay의 코드 덕분에 스크롤 뷰 안에서 목록 뷰를 가질 수 없지만 그런 것이 필요할 때를 위한 제 코드입니다.
LayoutInflater li = LayoutInflater.from(this);
RelativeLayout parent = (RelativeLayout) this.findViewById(R.id.relativeLayoutCliente);
int recent = 0;
for(Contatto contatto : contatti)
{
View inflated_layout = li.inflate(R.layout.header_listview_contatti, layout, false);
inflated_layout.setId(contatto.getId());
((TextView)inflated_layout.findViewById(R.id.textViewDescrizione)).setText(contatto.getDescrizione());
((TextView)inflated_layout.findViewById(R.id.textViewIndirizzo)).setText(contatto.getIndirizzo());
((TextView)inflated_layout.findViewById(R.id.textViewTelefono)).setText(contatto.getTelefono());
((TextView)inflated_layout.findViewById(R.id.textViewMobile)).setText(contatto.getMobile());
((TextView)inflated_layout.findViewById(R.id.textViewFax)).setText(contatto.getFax());
((TextView)inflated_layout.findViewById(R.id.textViewEmail)).setText(contatto.getEmail());
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
if (recent == 0)
{
relativeParams.addRule(RelativeLayout.BELOW, R.id.headerListViewContatti);
}
else
{
relativeParams.addRule(RelativeLayout.BELOW, recent);
}
recent = inflated_layout.getId();
inflated_layout.setLayoutParams(relativeParams);
//inflated_layout.setLayoutParams( new RelativeLayout.LayoutParams(source));
parent.addView(inflated_layout);
}
상대적인 레이아웃은 스크롤 뷰 내부에 머물기 때문에 모두 스크롤이 가능해집니다. :)
완벽하게 작동시켜야 한다는 @djunod의 답변에 대한 약간의 수정 사항이 있습니다.
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if(listAdapter == null) return;
if(listAdapter.getCount() <= 1) return;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
int totalHeight = 0;
View view = null;
for(int i = 0; i < listAdapter.getCount(); i++)
{
view = listAdapter.getView(i, view, listView);
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
비록 제안된 setListView대부분의 경우에서 높이 기반 어린이() 방법이 작동하며, 특히 많은 항목에서 마지막 요소가 표시되지 않는 것을 확인했습니다.그래서 어댑터 코드를 재사용하기 위해 간단한 버전의 ListView 동작을 모방하기로 결정했습니다. ListView의 대안은 다음과 같습니다.
import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
public class StretchedListView extends LinearLayout {
private final DataSetObserver dataSetObserver;
private ListAdapter adapter;
private OnItemClickListener onItemClickListener;
public StretchedListView(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(LinearLayout.VERTICAL);
this.dataSetObserver = new DataSetObserver() {
@Override
public void onChanged() {
syncDataFromAdapter();
super.onChanged();
}
@Override
public void onInvalidated() {
syncDataFromAdapter();
super.onInvalidated();
}
};
}
public void setAdapter(ListAdapter adapter) {
ensureDataSetObserverIsUnregistered();
this.adapter = adapter;
if (this.adapter != null) {
this.adapter.registerDataSetObserver(dataSetObserver);
}
syncDataFromAdapter();
}
protected void ensureDataSetObserverIsUnregistered() {
if (this.adapter != null) {
this.adapter.unregisterDataSetObserver(dataSetObserver);
}
}
public Object getItemAtPosition(int position) {
return adapter != null ? adapter.getItem(position) : null;
}
public void setSelection(int i) {
getChildAt(i).setSelected(true);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public ListAdapter getAdapter() {
return adapter;
}
public int getCount() {
return adapter != null ? adapter.getCount() : 0;
}
private void syncDataFromAdapter() {
removeAllViews();
if (adapter != null) {
int count = adapter.getCount();
for (int i = 0; i < count; i++) {
View view = adapter.getView(i, null, this);
boolean enabled = adapter.isEnabled(i);
if (enabled) {
final int position = i;
final long id = adapter.getItemId(position);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(null, v, position, id);
}
}
});
}
addView(view);
}
}
}
}
이 모든 대답들이 틀렸습니다!!!목록 보기를 스크롤 보기에 넣으려는 경우 설계를 다시 생각해야 합니다.스크롤 뷰를 스크롤 뷰에 넣으려고 합니다.목록에 간섭하면 목록 성능이 저하됩니다.이것은 안드로이드가 디자인한 것입니다.
목록을 다른 요소와 동일한 스크롤로 하려면 어댑터의 간단한 스위치 문을 사용하여 목록 맨 위에 다른 항목을 추가하기만 하면 됩니다.
class MyAdapter extends ArrayAdapter{
public MyAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewItem viewType = getItem(position);
switch(viewType.type){
case TEXTVIEW:
convertView = layouteInflater.inflate(R.layout.textView1, parent, false);
break;
case LISTITEM:
convertView = layouteInflater.inflate(R.layout.listItem, parent, false);
break; }
return convertView;
}
}
목록 어댑터는 보이는 것만 렌더링하기 때문에 모든 것을 처리할 수 있습니다.
LinearLayout에 정해진 Adapter 메서드가 있다면 이 모든 문제는 해결될 것입니다. 왜냐하면 다른 사용자에게 대신 사용하라고 했을 때 그 대안은 사소한 것이 될 것이기 때문입니다.
다른 스크롤 보기 안에서 목록 보기를 스크롤하려면 이 방법이 도움이 되지 않지만 그렇지 않으면 최소한 아이디어를 얻을 수 있습니다.
스크롤할 모든 콘텐츠를 결합하고 ListView의 어댑터를 설정하려면 사용자 지정 어댑터를 만들어야 합니다.
샘플 코드를 가지고 있지는 않지만, 혹시 당신이 원하는 것 같은 것이 있다면요.
<ListView/>
(other content)
<ListView/>
그런 다음 해당 내용을 모두 나타내는 어댑터를 생성해야 합니다.ListView/Adapters는 다양한 유형을 처리할 수 있을 정도로 스마트하지만 어댑터를 직접 작성해야 합니다.
안드로이드 UI API는 다른 모든 것만큼 성숙하지 않기 때문에 다른 플랫폼과 같은 장점을 가지고 있지 않습니다.또한 안드로이드에서 어떤 작업을 수행할 때는 더 작은 부품의 기능을 조립하고 작동하기 위해 여러 코드를 직접 작성해야 하는 안드로이드(Unix) 마인드를 가져야 합니다.
배치할때ListView
안에서.ScrollView
두가지 문제가 생깁니다.하나는ScrollView
UNSPECTED 모드에서 자식을 측정합니다.ListView
하나의 항목만 수용할 수 있도록 자체 높이를 설정합니다(이유는 모르겠습니다). 또 다른 항목은ScrollView
터치 이벤트를 차단합니다.ListView
스크롤되지 않습니다.
하지만 우리는 배치할 수 있습니다.ListView
안에서.ScrollView
약간의 해결책을 가지고이 게시물은 제가 해결 방법을 설명합니다.이 해결책을 통해 우리는 또한 유지할 수 있습니다.ListView
의 재활용 기능도 있습니다.
목록 보기를 Scrollview 안에 넣는 대신, 목록 보기와 Scrollview의 열기 사이에 나머지 내용을 별도의 보기로 놓고 해당 보기를 목록 보기의 헤더로 설정합니다.결국 스크롤을 담당하는 목록 보기만 하게 됩니다.
사용하면 안 됩니다.listview
안에서.scrollview
. 대신 사용해야 합니다.NestedScrollView
부모 및 리사이클러뷰(RecyclerView)로 표시됩니다. 스크롤 문제를 많이 처리하기 때문입니다.
여기 리스트 뷰의 전체 높이를 계산하는 코드 버전이 있습니다.이 제품은 제게 적합합니다.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null || listAdapter.getCount() < 2) {
// pre-condition
return;
}
int totalHeight = 0;
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(BCTDApp.getDisplaySize().width, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup) listItem.setLayoutParams(lp);
listItem.measure(widthMeasureSpec, heightMeasureSpec);
totalHeight += listItem.getMeasuredHeight();
}
totalHeight += listView.getPaddingTop() + listView.getPaddingBottom();
totalHeight += (listView.getDividerHeight() * (listAdapter.getCount() - 1));
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight;
listView.setLayoutParams(params);
listView.requestLayout();
}
언급URL : https://stackoverflow.com/questions/3495890/how-can-i-put-a-listview-into-a-scrollview-without-it-collapsing
'programing' 카테고리의 다른 글
MySQLDB 패키지 설치 방법은?(가져오기 오류: setuptools라는 모듈이 없습니다.) (0) | 2023.09.11 |
---|---|
IIS에서 브라우저 캐싱 활용(구글 페이지 속도 문제) (0) | 2023.09.11 |
Node.js에서 S3 getObject의 응답을 얻는 방법은? (0) | 2023.09.11 |
formGroup은 FormGroup 인스턴스를 필요로 합니다. (0) | 2023.09.11 |
npm ERR!노드용 도커 이미지를 만드는 동안 트래커 "idealTree"가 이미 있습니다. (0) | 2023.09.11 |