Hoe kan ik een ListView in een ScrollView plaatsen zonder dat deze instort?

Ik heb gezocht naar oplossingen voor dit probleem en het enige antwoord dat ik kan vinden lijkt te zijn: “plaats geen ListView in een ScrollView“. Ik heb echter nog geen echte verklaring voor waaromgezien. De enige reden die ik kan vinden is dat Google vindt dat je dat niet zou moeten willen doen. Nou, dat doe ik, dus dat deed ik.

Dus de vraag is, hoe kun je een ListView in een ScrollView plaatsen zonder dat deze instort tot zijn minimale hoogte?


Antwoord 1, autoriteit 100%

Hier is mijn oplossing. Ik ben vrij nieuw op het Android-platform en ik weet zeker dat dit een beetje hackachtig is, vooral in het gedeelte over het rechtstreeks aanroepen van .measure en het rechtstreeks instellen van de eigenschap LayoutParams.height, maar het werkt .

Het enige wat u hoeft te doen is Utility.setListViewHeightBasedOnChildren(yourListView)aan te roepen en het formaat wordt aangepast aan de hoogte van de items.

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);
    }
}

Antwoord 2, autoriteit 75%

Het gebruik van een listviewom het niet te laten scrollen is extreem duur en druist in tegen het hele doel van listview. U moet dit NIETdoen. Gebruik in plaats daarvan een LinearLayout.


Antwoord 3, autoriteit 34%

Dit gaat zeker werken…………
Je hoeft alleen je <ScrollView ></ScrollView>in het lay-out XML-bestand te vervangen door deze Custom ScrollViewzoals <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;
    }
}

Antwoord 4, autoriteit 5%

Er is een ingebouwde instelling voor. Op de ScrollView:

android:fillViewport="true"

In Java,

mScrollView.setFillViewport(true);

Romain Guy legt het hier uitgebreid uit: http://www.curious- creature.org/2010/08/15/scrollviews-handy-trick/


Antwoord 5, autoriteit 4%

U maakt een aangepaste lijstweergave die niet kan worden gescrolld

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();    
    }
}

In uw lay-outbronnenbestand

<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>

In Java-bestand

Maak een object van uw customListview in plaats van ListView zoals:
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);


Antwoord 6, autoriteit 3%

We kunnen niet twee tegelijk scrollen. We zullen de totale lengte van ListView hebben en de lijstweergave uitbreiden met de totale hoogte. Dan kunnen we ListView direct in ScrollView toevoegen of LinearLayout gebruiken omdat ScrollView direct één kind heeft.
kopieer setListViewHeightBasedOnChildren(lv) methode in uw code en vouw listview uit, dan kunt u listview in scrollview gebruiken.
\layout xml-bestand

<?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>

onCreate-methode in Activity-klasse:

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);
      }

Antwoord 7, autoriteit 2%

Dit is het enige dat voor mij werkte:

vanaf Lollipop kun je

yourtListView.setNestedScrollingEnabled(true);

Dit schakelt genest scrollen in of uit voor deze weergave
als je achterwaartse compatibiliteit met een oudere versie van het besturingssysteem nodig hebt, moet je de RecyclerView gebruiken.


Antwoord 8, autoriteit 2%

U moet een ListView niet in een ScrollView plaatsen omdat een ListView al iseen ScrollView. Dus dat zou hetzelfde zijn als het plaatsen van een ScrollView in een ScrollView.

Wat probeer je te bereiken?


Antwoord 9, autoriteit 2%

Dit is een combinatie van de antwoorden van DougW, Good Guy Greg en Paul. Ik ontdekte dat het allemaal nodig was toen ik dit probeerde te gebruiken met een aangepaste lijstweergave-adapter en niet-standaard lijstitems, anders crashte de lijstweergave de toepassing (ook crashte met het antwoord van 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);
    }

Antwoord 10

Ik heb het Utilityvan @DougW omgezet in C# (gebruikt in Xamarin). Het volgende werkt prima voor items met een vaste hoogte in de lijst, en zal meestal goed zijn, of op zijn minst een goed begin, als slechts enkele items een beetje groter zijn dan het standaarditem.

// 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));
        }
    }
}

Bedankt @DougW, dit heeft me uit een moeilijke positie geholpen toen ik met OtherPeople’sCode moest werken. 🙂


Antwoord 11

Vroeger was het niet mogelijk. Maar met de release van nieuwe Appcompat-bibliotheken en Design-bibliotheken kan dit worden bereikt.

Je hoeft alleen maar NestedScrollView te gebruiken
https://developer.android.com/reference/android/ support/v4/widget/NestedScrollView.html

Ik weet niet of het wel of niet met Listview zal werken, maar wel met RecyclerView.

Codefragment:

<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>

Antwoord 12

hey, ik had een soortgelijk probleem. Ik wilde een lijstweergave weergeven die niet scrolde en ik ontdekte dat het manipuleren van de parameters werkte, maar inefficiënt was en zich op verschillende apparaten anders zou gedragen. Als gevolg hiervan is dit een deel van mijn planningscode die dit eigenlijk heel efficiënt doet .

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);
   }
}

Opmerking: als u dit gebruikt, zal notifyDataSetChanged();niet werken zoals bedoeld, omdat de weergaven niet opnieuw worden getekend.
Doe dit als je een work around nodig hebt

adapter.registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                removeAndRedrawViews();
            }
        });

Antwoord 13

Er zijn twee problemen bij het gebruik van een ListView in een ScrollView.

1- ListView moet volledig worden uitgevouwen tot de kinderhoogte. deze ListView lost dit op:

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));
    }
}

De hoogte van de verdeler moet 0 zijn, gebruik in plaats daarvan opvulling in rijen.

2- De ListView gebruikt aanraakgebeurtenissen, dus ScrollView kan niet zoals gewoonlijk worden gescrold. Deze ScrollView lost dit probleem op:

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);
    }
}

Dit is de beste manier die ik heb gevonden om het voor elkaar te krijgen!


Antwoord 14

Een oplossing die ik gebruik is om alle inhoud van de ScrollView (wat boven en onder de listView zou moeten zijn) toe te voegen als headerView en footerView in de ListView.

Zo werkt het, ook de convertview is weer zoals het zou moeten zijn.


Antwoord 15

dankzij Vinay’s codeis hier mijn code voor als je nog geen lijstweergave in een schuifweergave kunt hebben die je nodig hebt zoiets

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);
                }

de relatieve Lay-out blijft in een ScrollView, zodat het allemaal scrollbaar wordt 🙂


Antwoord 16

Hier is een kleine wijziging op @djunod‘s antwoorddat ik het perfect moet laten werken:

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();
}

Antwoord 17

probeer dit, dit werkt voor mij, ik ben vergeten waar ik het vond, ergens in de overloop van de stapel,
ik ben hier niet om uit te leggen waarom het niet werkt, maar dit is het antwoord :).

   final ListView AturIsiPulsaDataIsiPulsa = (ListView) findViewById(R.id.listAturIsiPulsaDataIsiPulsa);
    AturIsiPulsaDataIsiPulsa.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;
        }
    });
    AturIsiPulsaDataIsiPulsa.setClickable(true);
    AturIsiPulsaDataIsiPulsa.setAdapter(AturIsiPulsaDataIsiPulsaAdapter);

EDIT!, ik ben er eindelijk achter waar ik de code vandaan heb. hier ! : ListView in ScrollView scrollt niet op Android


Antwoord 18

Hoewel de voorgestelde setListViewHeightBasedOnChildren()methoden in de meeste gevallen werken, in sommige gevallen, vooral met veel items, merkte ik dat de laatste elementen niet worden weergegeven. Dus besloot ik een eenvoudigeversie van het ListView-gedrag na te bootsen om elke Adapter-code opnieuw te gebruiken, hier is het het ListView-alternatief:

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);
        }
    }
}
}

Antwoord 19

Al deze antwoorden zijn fout!!!
Als u een lijstweergave in een schuifweergave probeert te plaatsen, moet u uw ontwerp heroverwegen. U probeert een ScrollView in een ScrollView te plaatsen. Het verstoren van de lijst zal de prestaties van de lijst schaden. Het is zo ontworpen door Android.

Als je echt wilt dat de lijst in dezelfde scroll staat als de andere elementen, hoef je alleen maar de andere items bovenaan de lijst toe te voegen met een simpele switch-instructie in je adapter:

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;
    }
}

De lijstadapter kan alles aan, omdat hij alleen weergeeft wat zichtbaar is.


Antwoord 20

Dit hele probleem zou verdwijnen als LinearLayout een setAdapter-methode had, want als je dan iemand zou vertellen het te gebruiken, zou het alternatief triviaal zijn.

Als je echt een scrollende ListView binnen een andere scrollende view wilt, zal dit niet helpen, maar anders geeft dit je in ieder geval een idee.

U moet een aangepaste adapter maken om alle inhoud waar u doorheen wilt bladeren te combineren en de ListView-adapter daarop in te stellen.

Ik heb geen voorbeeldcode bij de hand, maar als je zoiets wilt.

<ListView/>
(other content)
<ListView/>

Vervolgens moet u een adapter maken die al die inhoud vertegenwoordigt. De ListView/Adapters zijn slim genoeg om ook verschillende typen aan te kunnen, maar u moet de adapter zelf schrijven.

De Android UI API is gewoon niet zo volwassen als vrijwel al het andere dat er is, dus het heeft niet dezelfde finesses als andere platforms. Als je iets op Android doet, moet je ook in een Android (unix) -mentaliteit zijn, waarbij je verwacht dat om alles te doen, je waarschijnlijk functionaliteit van kleinere onderdelen moet samenstellen en een heleboel eigen code moet schrijven om het te krijgen werk.


Antwoord 21

Als we listviewin scrollviewplaatsen, ontstaan ​​er twee problemen. Een daarvan is dat scrollviewzijn kinderen meet in de NIET-GESPECIFICEERDE modus, dus listviewstelt zijn eigen hoogte in voor slechts één item (ik weet niet waarom), een andere is scrollviewonderschept de aanraakgebeurtenis zodat listviewniet scrollt.

Maar we kunnenlistviewin scrollviewplaatsen met een tijdelijke oplossing. Dit bericht, door mij, legt de tijdelijke oplossing uit . Door deze tijdelijke oplossing kunnen we ook de recyclingfunctie van listviewbehouden.


Antwoord 22

In plaats van de lijstweergave in Scrollview te plaatsen, plaatst u de rest van de inhoud tussen de lijstweergave en de opening van de Scrollview als een aparte weergave en stelt u die weergave in als de kop van de lijstweergave. U zult dus uiteindelijk alleen de lijstweergave overnemen die de leiding heeft over Scroll.


Antwoord 23

Dezebibliotheek is de gemakkelijkste en snelste oplossing voor het probleem.


Antwoord 24

Gebruik listviewnooit in scrollview. In plaats daarvan moet je NestedScrollViewals ouder gebruiken en daarbinnen RecyclerView… omdat het veel scrollproblemen afhandelt


Antwoord 25

Hier is mijn versie van de code die de totale hoogte van de lijstweergave berekent. Deze werkt voor mij:

  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();
}

Other episodes