web-dev-qa-db-de.com

Android-Listenansicht in einer Bildlaufansicht

Ich habe ein Android-Layout, das eine scrollView mit einer Anzahl von Elementen enthält. Am unteren Rand der Variable scrollView habe ich eine Variable listView, die dann von einem Adapter aufgefüllt wird.

Das Problem, das ich habe, ist, dass Android listView von scrollView ausschließt, da scrollView bereits eine scrollbare Funktion hat. Ich möchte, dass die Variable listView so lang ist, wie der Inhalt ist und dass die Bildlaufansicht des Masters scrollbar ist.

Wie kann ich dieses Verhalten erreichen?

Hier ist mein Hauptlayout:

<ScrollView
    Android:id="@+id/scrollView1"
    Android:layout_width="match_parent"
    Android:layout_height="0dp"
    Android:layout_weight="2"
    Android:fillViewport="true"
    Android:gravity="top" >

    <LinearLayout
        Android:id="@+id/foodItemActvity_linearLayout_fragments"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical" >
    </LinearLayout>

</ScrollView>

Ich füge meine Komponenten dann programmgesteuert mit der id: foodItemActvity_linearLayout_fragments zum linearlayour hinzu. Unten sehen Sie eine der Ansichten, die in das lineare Layout geladen werden. Dies ist derjenige, der mir Probleme mit den Rollen macht.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical" >

    <TextView
       Android:id="@+id/fragment_dds_review_textView_label"
       Android:layout_width="wrap_content"
       Android:layout_height="wrap_content"
       Android:text="Reviews:"
       Android:textAppearance="?android:attr/textAppearanceMedium" />

   <ListView
       Android:id="@+id/fragment_dds_review_listView"
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content">
   </ListView>
</LinearLayout>

Mein Adapter füllt dann diese Listenansicht.

Hier ist ein Bild aus dem Android-Hierarchie-Viewer, wenn ich auf den Master-ScrollView klicke:

 Android List View inside a scroll view

Wie Sie sehen, wird die Liste mit den Bewertungen nicht angezeigt.

Ich sollte in der Lage sein, die Seite nach unten zu scrollen und 8 Bewertungen anzuzeigen, aber stattdessen werden mir nur diese 3 angezeigt, und ich kann auf dem winzigen Bereich blättern, in dem sich die Bewertungen befinden. Ich möchte eine globale Seite blättern

241
Zapnologica

Die kürzeste und einfachste Lösung für das ListView in einem ScrollView - Problem.

Sie müssen in der Datei layout.xml keine besonderen Aktionen durchführen und auch nicht mit der übergeordneten ScrollView-Komponente umgehen. Sie müssen nur die untergeordnete ListView handhaben. Sie können diesen Code auch verwenden, um alle Arten von untergeordneten Ansichten in einer ScrollView zu verwenden und Touch-Vorgänge auszuführen.

Fügen Sie einfach diese Codezeilen in Ihre Java-Klasse ein:

ListView lv = (ListView) findViewById(R.id.layout_lv);
lv.setOnTouchListener(new OnTouchListener() {
    // Setting on Touch Listener for handling the touch inside ScrollView
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    // Disallow the touch request for parent scroll on touch of child view
    v.getParent().requestDisallowInterceptTouchEvent(true);
    return false;
    }
});

Wenn Sie ListView in ein ScrollView einfügen, dehnt sich das ListView nicht auf seine volle Höhe aus. Im Folgenden finden Sie eine Methode zur Behebung dieses Problems.

/**** Method for Setting the Height of the ListView dynamically.
 **** Hack to fix the issue of not showing all the items of the ListView
 **** when placed inside a ScrollView  ****/
public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null)
        return;

    int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
    int totalHeight = 0;
    View view = null;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        view = listAdapter.getView(i, view, listView);
        if (i == 0)
            view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT));

        view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
        totalHeight += view.getMeasuredHeight();
    }
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
}

Um diese Methode zu verwenden, übergeben Sie einfach die ListView innerhalb dieser Methode:

ListView list = (ListView) view.findViewById(R.id.ls);
setListViewHeightBasedOnChildren(list);

Zur Verwendung mit ExpandableListView - credit Benny

ExpandableListView: view = listAdapter.getView(0, view, listView);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.MATCH_PARENT, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);

Für ListView mit variabler Artikelhöhe verwenden Sie den folgenden Link:

ListView in ScrollView scrollt auf Android nicht

Für die Bibliothek zur direkten Implementierung in Ihrem Code - credit Paolo Rotolo

https://github.com/PaoloRotolo/ExpandableHeightListView

533
arshu

Die Antwort ist einfach und ich bin überrascht, dass sie hier noch nicht beantwortet wurde.

Verwenden Sie einen Header View oder/und Footer View in der Liste selbst .__ Mischen Sie keine ScrollView mit einer ListView oder etwas, das scrollen kann. Es soll mit Kopf- und Fußzeilen verwendet werden :)

Übernehmen Sie den gesamten Inhalt über Ihrer ListView, fügen Sie ihn als Layout in eine andere XML-Datei ein, blenden Sie ihn auf und fügen Sie ihn der Liste als Header-Ansicht hinzu.

d.h.

View header = getLayoutInflater().inflate(R.layout.header, null);
View footer = getLayoutInflater().inflate(R.layout.footer, null);
listView.addHeaderView(header);
listView.addFooterView(footer);
213
ericosg

Ich weiß, es ist schon so lange her, aber ich habe auch dieses Problem, habe diese Lösung ausprobiert und es funktioniert. Ich denke, es kann auch den anderen helfen.

Ich füge Android hinzu: fillViewport = "true" in der Layout-XML für das scrollView . Alles in allem wird mein ScrollView also so sein.

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/scrollView6" 
    Android:fillViewport="true">

Und es funktioniert für mich wie Magie. Die ListView, die sich in meiner ScrollView befindet, wird wieder auf ihre Größe erweitert.

Hier ist der vollständige Beispielcode für die ScrollView und die ListView.

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/scrollView6" Android:fillViewport="true">
    <LinearLayout
        Android:orientation="vertical"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">
        ....
        <ListView
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:id="@+id/lv_transList" Android:layout_gravity="top"
            Android:layout_marginTop="5dp"/>
        ....
    </LinearLayout>
</ScrollView>
33
acyn

Sie erstellen eine benutzerdefinierte ListView, die nicht scrollbar ist

  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 Ihrer Layout-Ressourcendatei

     <?xml version="1.0" encoding="utf-8"?>
        <ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:fadingEdgeLength="0dp"
            Android:fillViewport="true"
            Android:overScrollMode="never"
            Android:scrollbars="none" >

            <RelativeLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" >

                <!-- com.Example Changed with your Package name -->

                <com.Example.NonScrollListView
                    Android:id="@+id/lv_nonscroll_list"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content" >
                </com.Example.NonScrollListView>

                <RelativeLayout
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:layout_below="@+id/lv_nonscroll_list" >

                    <!-- Your another layout in scroll view -->

                </RelativeLayout>
            </RelativeLayout>

        </ScrollView>

In Java-Datei Erstellen Sie ein Objekt Ihrer benutzerdefinierten Listenansicht anstelle von ListView wie: NonScrollListView non_scroll_list = (NonScrollListView)

15
    public static void setListViewHeightBasedOnChildren(ListView listView) {
    // 获取ListView对应的Adapter
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        return;
    }

    int totalHeight = 0;
    for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0); // 计算子项View 的宽高
        totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    // listView.getDividerHeight()获取子项间分隔符占用的高度
    // params.height最后得到整个ListView完整显示需要的高度
    listView.setLayoutParams(params);
}

sie können diesen Code für die Listenansicht in der Scrollansicht verwenden

8
Su Zhenpeng

Sie können das Problem lösen, indem Sie Android:fillViewport="true" zu Ihrem ScrollView hinzufügen.

<ScrollView
      Android:layout_width="match_parent"
      Android:layout_height="match_parent"
      Android:background="@color/white"
      Android:fillViewport="true"
      Android:scrollbars="vertical">

<ListView
      Android:id="@+id/statusList"
      Android:layout_width="fill_parent"
      Android:layout_height="wrap_content"
      Android:animationCache="false"
      Android:divider="@null"
      Android:scrollingCache="false"
      Android:smoothScrollbar="true" />

</ScrollView>


vor der Verwendung dieser Eigenschaft war nur ein untergeordnetes Element meiner Listenansicht sichtbar. Danach werden alle Zeilen oder untergeordneten Elemente der Liste angezeigt.

8
MV53

Dieser Code löst Ihr Problem, wenn Sie nur eine ListView in einen Code implementiert haben.

Wenn Sie RelativeLayout als untergeordnetes ListView verwenden, geben Sie diesen Code hier als NullPointerException zurück. listItem.measure (0, 0); , wegen RelativeLayout.Und die Lösung wird Ihr Relativelayout in ein LinearLayout eingefügt, und es wird gut funktionieren.

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter(); 
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}
6
krunal shah

Ich werde es hier belassen, falls jemand das gleiche Problem hat. Ich musste eine ListView in eine ScrollView einfügen. ListView mit Header war aus mehreren Gründen keine Option. Es war auch keine Option zur Verwendung von LinearLayout anstelle von ListView. Ich folgte der akzeptierten Lösung, aber es funktionierte nicht, da die Elemente in der Liste ein komplexes Layout mit mehreren Zeilen hatten und jedes Listenansichtselement eine variable Höhe hatte. Die Höhe wurde nicht richtig gemessen. Die Lösung bestand darin, jedes Element innerhalb der getView () - Methode von ListView Adapter zu messen.

@Override
public View getView(int position, View view, ViewGroup parent) {
    ViewHolder holder;
    if (view == null) {
        . . .
        view.setTag(holder);
    } else holder = (ViewHolder)view.getTag();
    . . .

    // measure ListView item (to solve 'ListView inside ScrollView' problem)
    view.measure(View.MeasureSpec.makeMeasureSpec(
                    View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    return view;
}
5
Alexander Zhak

Sie können ListView einfach in ScrollView einfügen Sie müssen nur die Höhe von ListView programmgesteuert ändern, wie folgt:

    ViewGroup.LayoutParams listViewParams = (ViewGroup.LayoutParams)listView.getLayoutParams();
    listViewParams.height = 400;
    listView.requestLayout();

Das funktioniert perfekt!

4
Taras Okunev

Nach vielen Forschungs- und Entwicklungsarbeiten erledigt:

fragment_one.xml sollte folgendermaßen aussehen:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/scrollViewParent"
    Android:orientation="vertical" >

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical" >

        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="400dip" >

            <ListView
                Android:id="@+id/listView"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent" />

            <View
                Android:id="@+id/customView"
                Android:layout_width="fill_parent"
                Android:layout_height="fill_parent"
                Android:background="@Android:color/transparent" />
        </RelativeLayout>

        <!-- Your other elements are here -->

    </LinearLayout>

</ScrollView>

Ihre Java-Klasse von FragmentOne.Java sieht folgendermaßen aus:

private ListView listView;
private View customView

onCreateView

listView = (ListView) rootView.findViewById(R.id.listView);
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);

customView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        // Disallow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        // Disable touch on transparent view
                        return false;

                    case MotionEvent.ACTION_UP:
                        // Allow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(false);
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        return false;

                    default:
                        return true;
                }
            }
        });
4
Hiren Patel

Tun Sie nichts in Parent ScrollView. Tun Sie dies nur für die untergeordnete ListView. Alles wird perfekt funktionieren. 

mListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mScrollView.requestDisallowInterceptTouchEvent(true);
               int action = event.getActionMasked();
                switch (action) {
                    case MotionEvent.ACTION_UP:
                        mScrollView.requestDisallowInterceptTouchEvent(false);
                        break;
                }
                return false;
            }
        });
4
Sibin

Ich hatte ein ähnliches Problem wie das Originalposter - wie kann ich die Listenansicht in der Bildlaufleiste scrollen lassen - und diese Antwort löste mein Problem .. /. Deaktivieren des Bildlaufs einer in einer Bildlaufansicht enthaltenen ListView

Ich habe keine neuen Fragmente in bestehende Layouts oder ähnliches gerufen, wie das OP es tat, also würde mein Code so aussehen:

<ScrollView
    Android:id="@+id/scrollView1"
    Android:layout_width="match_parent"
    Android:layout_height="0dp"
    Android:layout_weight="2"
    Android:fillViewport="true"
    Android:gravity="top" >

 <LinearLayout
        Android:id="@+id/foodItemActvity_linearLayout_fragments"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical" >


    <TextView
       Android:id="@+id/fragment_dds_review_textView_label"
       Android:layout_width="wrap_content"
       Android:layout_height="wrap_content"
       Android:text="Reviews:"
       Android:textAppearance="?android:attr/textAppearanceMedium" />

   <ListView
       Android:id="@+id/my_listView"
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content">
   </ListView>

</LinearLayout>

</ScrollView>

Im Grunde überprüfe ich die Länge der Listenansicht, bevor ich sie anrufe, und wenn ich sie anrufe, mache ich sie in diese Länge. Verwenden Sie in Ihrer Java-Klasse diese Funktion:

public static void justifyListViewHeightBasedOnChildren (ListView listView) {

    ListAdapter adapter = listView.getAdapter();

    if (adapter == null) {
        return;
    }
    ViewGroup vg = listView;
    int totalHeight = 0;
    for (int i = 0; i < adapter.getCount(); i++) {
        View listItem = adapter.getView(i, null, vg);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams par = listView.getLayoutParams();
    par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
    listView.setLayoutParams(par);
    listView.requestLayout();
}

Und rufen Sie die Funktion so auf:

justifyListViewHeightBasedOnChildren(listView);

Das Ergebnis ist eine Listenansicht ohne Bildlaufleiste. Die gesamte Länge der angezeigten Listenansicht wird mit der Bildlaufleiste der Bildlaufansicht gescrollt.

3
CHarris

Sie können alles in ein lineares Layout setzen. Erstellen Sie also ein lineares Layout, und es werden 2 untergeordnete Elemente, eine Bildlaufansicht und ein weiteres lineares Layout angezeigt. Geben Sie ihnen die Layoutgewichte und los geht's:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >

<ScrollView
    Android:layout_width="fill_parent"
    Android:layout_height="0dip" Android:layout_weight="0.8">

    <LinearLayout
        Android:id="@+id/seTaskActivityRoot"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:background="@color/white"
        Android:orientation="vertical" >

        <TextView
            Android:id="@+id/textView1"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="@string/taskName" />


        <Spinner
            Android:id="@+id/seTaskPrioritiesSP"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content"
            Android:layout_weight="1" />

        <TextView
            Android:id="@+id/textView4"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="@string/taskTargetInNumeric" />

        <Spinner
            Android:id="@+id/seTaskUnitsSP"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_weight="1" />

        <TextView
            Android:id="@+id/textView6"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="@string/newTaskCurrentStatus" />

        <EditText
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:ems="10"
            Android:hint="@string/addTaskCurrentStatus"
            Android:inputType="numberDecimal" />


    </LinearLayout>
</ScrollView>

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="0dip"
    Android:orientation="vertical" Android:layout_weight="0.2">

    <TextView
        Android:id="@+id/textView8"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="TextView" />

    <ListView
        Android:id="@+id/logList"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

3
Jeyhun Karimov

Wie andere bereits erwähnt haben, verwenden Sie ListView nicht in einem ScrollView.

Um dieses Problem zu umgehen, können Sie ein LinearLayout verwenden, aber um die Dinge trotzdem sauber zu halten: Füllen Sie Ihr LinearLayout mit einem Adapter auf, genau wie bei einer ListView

Sie können diese Klasse als LinearLayout-Ersatz verwenden, der Adapter unterstützt

import Android.content.Context;
import Android.database.DataSetObserver;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.BaseAdapter;
import Android.widget.LinearLayout;

public class AdaptableLinearLayout extends LinearLayout {

private BaseAdapter mAdapter;

private int mItemCount = 0;

private boolean mDisableChildrenWhenDisabled = false;

private int mWidthMeasureSpec;
private int mHeightMeasureSpec;


public AdaptableLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

public BaseAdapter getAdapter() {
    return mAdapter;
}

public void setAdapter(BaseAdapter adapter) {
    mAdapter = adapter;
    adapter.registerDataSetObserver(new DataSetObserver() {
        @Override
        public void onChanged() {
            updateLayout();
            super.onChanged();
        }

        @Override
        public void onInvalidated() {
            updateLayout();
            super.onInvalidated();
        }
    });
    updateLayout();
}

private void updateLayout() {
    mItemCount = mAdapter.getCount();
    requestLayout();
    invalidate();
}

/**
 * set size for the current View
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mWidthMeasureSpec = widthMeasureSpec;
    mHeightMeasureSpec = heightMeasureSpec;

    removeAllViewsInLayout();
    for (int i = 0; i < mItemCount; i++) {
        makeAndAddView(i);
    }
}

private View makeAndAddView(int position) {
    View child;

    // Nothing found in the recycler -- ask the adapter for a view
    child = mAdapter.getView(position, null, this);

    // Position the view
    setUpChild(child, position);

    return child;

}

private void setUpChild(View child, int position) {

    ViewGroup.LayoutParams lp = child.getLayoutParams();
    if (lp == null) {
        lp = generateDefaultLayoutParams();
    }
    addViewInLayout(child, position, lp);

    // Get measure specs
    int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), lp.height);
    int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);

    // Measure child
    child.measure(childWidthSpec, childHeightSpec);

    int childLeft;
    int childRight;

    // Position vertically based on gravity setting
    int childTop = getPaddingTop() + ((getMeasuredHeight() - getPaddingBottom() - getPaddingTop() - child.getMeasuredHeight()) / 2);
    int childBottom = childTop + child.getMeasuredHeight();

    int width = child.getMeasuredWidth();
    childLeft = 0;
    childRight = childLeft + width;

    child.layout(childLeft, childTop, childRight, childBottom);

    if (mDisableChildrenWhenDisabled) {
        child.setEnabled(isEnabled());
    }
}
}
3
AAverin

Sie sollten niemals eine ScrollView mit einer ListView verwenden, da ListView für den eigenen vertikalen Bildlauf sorgt. Dies bedeutet vor allem, dass alle wichtigen Optimierungen in ListView für den Umgang mit großen Listen missachtet werden, da ListView dadurch gezwungen wird, die gesamte Liste der Elemente anzuzeigen, um den von ScrollView bereitgestellten unendlichen Container aufzufüllen.

http://developer.Android.com/reference/Android/widget/ScrollView.html

3
Muhammad Asim

Aktualisieren

<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >

<LinearLayout
    Android:id="@+id/foodItemActvity_linearLayout_fragments"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical" >
</LinearLayout>

zu 

<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >

<LinearLayout
    Android:id="@+id/foodItemActvity_linearLayout_fragments"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical" >
</LinearLayout>

Der Punkt hier ist, dass Sie versuchen, die Höhe auf 0dp einzustellen (fest).

2
Rajnish Mishra

ich habe eine Lösung für scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> dynamische Listenansicht gefunden, aber ich bin nicht der Autor. Es gibt ein paar Fehler, aber zumindest funktioniert es

public class CustomPager extends ViewPager {

    private View mCurrentView;

    public CustomPager(Context context) {
        super(context);
    }

    public CustomPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mCurrentView == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        int height = 0;
        mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = mCurrentView.getMeasuredHeight();
        if (h > height) height = h;
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void measureCurrentView(View currentView) {
        mCurrentView = currentView;
        this.post(new Runnable() {
            @Override
            public void run() {
                requestLayout();
            }
        });
    }

    public int measureFragment(View view) {
        if (view == null)
            return 0;

        view.measure(0, 0);
        return view.getMeasuredHeight();
    }
}


public class MyPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments;
    private int mCurrentPosition = -1;


    public MyPagerAdapter(FragmentManager fm) {
        super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
        this.fragments = new ArrayList<Fragment>();
        fragments.add(new FirstFragment());
        fragments.add(new SecondFragment());
        fragments.add(new ThirdFragment());
        fragments.add(new FourthFragment());
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        super.setPrimaryItem(container, position, object);
        if (position != mCurrentPosition) {
            Fragment fragment = (Fragment) object;
            CustomPager pager = (CustomPager) container;
            if (fragment != null && fragment.getView() != null) {
                mCurrentPosition = position;
                pager.measureCurrentView(fragment.getView());
            }
        }
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

fragmente-Layout kann alles sein

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
Android:orientation="vertical"
    Android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">


    <ListView
        Android:id="@+id/lv1"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#991199"/>
</LinearLayout>

dann einfach irgendwo

lv = (ListView) view.findViewById(R.id.lv1);
        lv.setAdapter(arrayAdapter);
        setListViewHeightBasedOnChildren(lv);
    }

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null)
            return;

        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                View.MeasureSpec.UNSPECIFIED);
        int totalHeight = 0;
        View view = null;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            view = listAdapter.getView(i, view, listView);
            if (i == 0)
                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
                        LinearLayout.LayoutParams.WRAP_CONTENT));

            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
2
bedman

Meine Anforderung ist es, eine ListView von Elementen gleicher Größe in eine ScrollView aufzunehmen. Ich habe einige der anderen hier aufgeführten Lösungen ausprobiert, die ListView schien nicht richtig zu dimensionieren (entweder zu wenig Platz oder zu viel). Folgendes hat für mich funktioniert:

    public static void expandListViewHeight(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null)
        return;

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    listView.measure(0, 0);
    params.height = listView.getMeasuredHeight() * listAdapter.getCount() + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
}

Hoffe das hilft jemandem.

2
Malcolm Bryant

In xml:

<com.example.util.NestedListView
                    Android:layout_marginTop="10dp"
                    Android:id="@+id/listview"
                    Android:layout_width="fill_parent"
                    Android:layout_height="fill_parent"
                    Android:divider="@null"

                    Android:layout_below="@+id/rl_delivery_type" >
                </com.example.util.NestedListView>

In Java:

public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener {

    private int listViewTouchAction;
    private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;

    public NestedListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        listViewTouchAction = -1;
        setOnScrollListener(this);
        setOnTouchListener(this);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
            if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
                scrollBy(0, -1);
            }
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int newHeight = 0;
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode != MeasureSpec.EXACTLY) {
            ListAdapter listAdapter = getAdapter();
            if (listAdapter != null && !listAdapter.isEmpty()) {
                int listPosition = 0;
                for (listPosition = 0; listPosition < listAdapter.getCount()
                        && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
                    View listItem = listAdapter.getView(listPosition, null, this);
                    //now it will not throw a NPE if listItem is a ViewGroup instance
                    if (listItem instanceof ViewGroup) {
                        listItem.setLayoutParams(new LayoutParams(
                                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                    }
                    listItem.measure(widthMeasureSpec, heightMeasureSpec);
                    newHeight += listItem.getMeasuredHeight();
                }
                newHeight += getDividerHeight() * listPosition;
            }
            if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
                if (newHeight > heightSize) {
                    newHeight = heightSize;
                }
            }
        } else {
            newHeight = getMeasuredHeight();
        }
        setMeasuredDimension(getMeasuredWidth(), newHeight);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
            if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
                scrollBy(0, 1);
            }
        }
        return false;
    }
}
1
Makvin

Ok, hier ist meine Antwort. Die Methode, mit der die Höhe der ListView festgelegt wird, ist geschlossen, aber nicht perfekt. Falls die meisten Gegenstände die gleiche Höhe haben, funktionieren sie gut. Sollte dies nicht der Fall sein, gibt es ein großes Problem. Ich habe es viele Male versucht, und als ich den Wert von listItem.getMeasureHeight und listItem.getMeasuerWidth in das Protokoll eingetragen habe, habe ich gesehen, dass die Breitenwerte sehr unterschiedlich sind, was hier nicht erwartet wird, da alle Elemente in derselben ListView enthalten sein sollten haben die gleiche Breite. Und da geht der Fehler: 

Einige verwendeten Kennzahlen (0, 0), wodurch die Ansicht tatsächlich in beide Richtungen ungebunden wurde und die Breite wild lief. Einige haben versucht, die Breite von listView zu erhalten, geben aber 0 zurück, was bedeutungslos ist. 

Wenn ich weiter lese, wie Android die Ansicht rendert, ist mir klar, dass dieser Versuch die gesuchte Antwort nicht erreichen kann, es sei denn, diese Funktionen werden ausgeführt, nachdem die Ansicht gerendert wurde. 

Dieses Mal verwende ich den getViewTreeObserver für die ListView, die ich Höhe festlegen möchte, und addOnGlobalLayoutListener. Innerhalb dieser Methode deklariere ich einen neuen OnGlobalLayoutListener, in dem getWidth dieses Mal die tatsächliche Breite der ListView zurückgibt. 

private void getLayoutWidth(final ListView lv, final int pad){
        //final ArrayList<Integer> width = new ArrayList<Integer>();

        ViewTreeObserver vto = lv.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                lv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                //width.add(layout.getMeasuredWidth());
                int width = lv.getMeasuredWidth();
                ListUtils.setDynamicHeight(lv, width, pad);
            }
        });
    }

public static class ListUtils {
        //private static final int UNBOUNDED = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        public static void setDynamicHeight(ListView mListView, int width, int pad) {
            ListAdapter mListAdapter = mListView.getAdapter();
            mListView.getParent();
            if (mListAdapter == null) {
                // when adapter is null
                return;
            }
            int height = 0;


            int desiredWidth = View.MeasureSpec.makeMeasureSpec(width - 2*pad, View.MeasureSpec.EXACTLY);
            for (int i = 0; i < mListAdapter.getCount(); i++) {
                View listItem = mListAdapter.getView(i, null, mListView);

                listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
                //listItem.measure(UNBOUNDED, UNBOUNDED);
                height += listItem.getMeasuredHeight() + 2*pad;
                Log.v("ViewHeight :", mListAdapter.getClass().toString() + " " + listItem.getMeasuredHeight() + "--" + listItem.getMeasuredWidth());
            }
            ViewGroup.LayoutParams params = mListView.getLayoutParams();
            params.height = height + (mListView.getDividerHeight() * (mListAdapter.getCount() - 1));
            mListView.setLayoutParams(params);
            mListView.requestLayout();
        }
    }

Das Value Pad ist die Auffüllung, die ich im ListView-Layout festgelegt habe. 

1

verwenden dieser ListView Für mich gearbeitet

   package net.londatiga.Android.widget;

      import Android.util.AttributeSet;
      import Android.view.ViewGroup;
      import Android.widget.ListView;
      import Android.content.Context;

   public class ExpandableHeightListView extends ListView
      {

    boolean expanded = false;

      public ExpandableHeightListView(Context context)
    {
    super(context);
}

public ExpandableHeightListView(Context context, AttributeSet attrs)
{
    super(context, attrs);
}

public ExpandableHeightListView(Context context, AttributeSet attrs,
        int defStyle)
{
    super(context, attrs, defStyle);
}

public boolean isExpanded()
{
    return expanded;
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    // HACK! TAKE THAT Android!
    if (isExpanded())
    {
        // Calculate entire height by providing a very large height hint.
        // But do not use the highest 2 bits of this integer; those are
        // reserved for the MeasureSpec mode.
        int expandSpec = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
    else
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

public void setExpanded(boolean expanded)
{
    this.expanded = expanded;
}
}

und in xml

            <com.pakagename.ExpandableHeightListView
                Android:id="@+id/expandableHeightListView"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" >
            </com.Example.ExpandableHeightListView>

und in MainActivity 

  ExpandableHeightListView listView = new ExpandableHeightListView(this);
    listview=(ExpandableHeightListView)findViewById(R.id.expandableHeightListView);
   listView.setAdapter(adapter); //set your adaper
   listView.setExpanded(true);

In diesem Artikel finden Sie weitere Informationen sowie Informationen dazu, wie Sie die Rasteransicht in der Bildlaufansicht anzeigen können

1
Manohar Reddy

Wenn Sie aus irgendeinem Grund addHeaderView und addFooterView nicht verwenden möchten, z. Wenn Sie mehrere Listen haben, wäre es eine gute Idee, ListAdapter erneut zu verwenden, um eine einfache LinearLayout aufzufüllen, sodass es keine Bildlauffunktionen gibt.

Wenn Sie bereits ein ganzes von ListFragment abgeleitetes Fragment haben und dieses mit einfachen LinearLayout in ein ähnliches Fragment konvertieren möchten, ohne einen Bildlauf durchzuführen (z. B. um es in ScrollView zu platzieren), können Sie ein Adapterfragment wie folgt implementieren:

// converts listFragment to linearLayout (no scrolling)
// please call init() after fragment is inflated to set listFragment to convert
public class ListAsArrayFragment extends Fragment {
    public ListAsArrayFragment() {}

    private ListFragment mListFragment;
    private LinearLayout mRootView;


    // please call me!
    public void init(Activity activity, ListFragment listFragment){
        mListFragment = listFragment;
        mListFragment.onAttach(activity);
        mListFragment.getListAdapter().registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                refreshView();
            }
        });
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // create an empty vertical LinearLayout as the root view of this fragment
        mRootView = new LinearLayout(getActivity());
        mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        mRootView.setOrientation(LinearLayout.VERTICAL);
        return mRootView;
    }

    // reusing views for performance
    // todo: support for more than one view type
    ArrayList<View> mViewsToReuse = new ArrayList<>();
    ArrayList<View> mCurrentViews = new ArrayList<>();

    // re-add views to linearLayout
    void refreshView(){

        // remove old views from linearLayout and move them to mViewsToReuse
        mRootView.removeAllViews();
        mViewsToReuse.addAll(mCurrentViews);
        mCurrentViews.clear();

        // create new views
        for(int i=0; i<mListFragment.getListAdapter().getCount(); ++i){
            View viewToReuse = null;
            if(!mViewsToReuse.isEmpty()){
                viewToReuse = mViewsToReuse.get(mViewsToReuse.size()-1);
                mViewsToReuse.remove(mViewsToReuse.size()-1);
            }
            final View view = mListFragment.getListAdapter().getView(i, viewToReuse, mRootView);
            ViewGroup.LayoutParams oldParams = view.getLayoutParams();
            view.setLayoutParams(new LinearLayout.LayoutParams(oldParams.width, oldParams.height));
            final int finalI = i;

            // pass click events to listFragment
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mListFragment.onListItemClick(null, view, finalI, finalI);
                }
            });
            mRootView.addView(view);
            mCurrentViews.add(view);
        }
    }

Möglicherweise möchten Sie onCreate, onPause, onResume usw. je nach Bedarf an das ursprüngliche Fragment weiterleiten oder anstelle der Komposition Vererbung versuchen (aber bestimmte Methoden überschreiben, sodass das ursprüngliche Fragment nicht tatsächlich an die Layout-Hierarchie angehängt wird). aber ich wollte das Originalfragment so weit wie möglich isolieren, weil wir nur seine Variable ListAdapter extrahieren müssen. Wenn Sie die setListAdapter des Originalfragments in onAttach aufrufen, reicht dies wahrscheinlich aus.

So verwenden Sie ListAsArrayFragment zum Einschließen von OriginalListFragment ohne Scrollen. In onCreate der übergeordneten Aktivität:

ListAsArrayFragment fragment = (ListAsArrayFragment) getFragmentManager().findFragmentById(R.id.someFragmentId);
OriginalListFragment originalFragment = new OriginalListFragment();
fragment.init(this, originalFragment);

// now access originalFragment.getListAdapter() to modify list entries
// and remember to call notifyDatasetChanged()
1
atablash

ich habe eine Lösung für scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> dynamische Listenansicht gefunden, aber ich bin nicht der Autor. 

public class CustomPager extends ViewPager {

    private View mCurrentView;

    public CustomPager(Context context) {
        super(context);
    }

    public CustomPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mCurrentView == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        int height = 0;
        mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = mCurrentView.getMeasuredHeight();
        if (h > height) height = h;
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void measureCurrentView(View currentView) {
        mCurrentView = currentView;
        this.post(new Runnable() {
            @Override
            public void run() {
                requestLayout();
            }
        });
    }

    public int measureFragment(View view) {
        if (view == null)
            return 0;

        view.measure(0, 0);
        return view.getMeasuredHeight();
    }
}


public class MyPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments;
    private int mCurrentPosition = -1;


    public MyPagerAdapter(FragmentManager fm) {
        super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
        this.fragments = new ArrayList<Fragment>();
        fragments.add(new FirstFragment());
        fragments.add(new SecondFragment());
        fragments.add(new ThirdFragment());
        fragments.add(new FourthFragment());
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        super.setPrimaryItem(container, position, object);
        if (position != mCurrentPosition) {
            Fragment fragment = (Fragment) object;
            CustomPager pager = (CustomPager) container;
            if (fragment != null && fragment.getView() != null) {
                mCurrentPosition = position;
                pager.measureCurrentView(fragment.getView());
            }
        }
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

fragmente-Layout kann alles sein

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
Android:orientation="vertical"
    Android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">


    <ListView
        Android:id="@+id/lv1"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#991199"/>
</LinearLayout>

dann einfach irgendwo

 lv = (ListView) view.findViewById(R.id.lv1);
        lv.setAdapter(arrayAdapter);
        setListViewHeightBasedOnChildren(lv);
    }

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null)
            return;

        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                View.MeasureSpec.UNSPECIFIED);
        int totalHeight = 0;
        View view = null;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            view = listAdapter.getView(i, view, listView);
            if (i == 0)
                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
                        LinearLayout.LayoutParams.WRAP_CONTENT));

            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
1
qwerty

Das hat für mich funktioniert ( link1 , link2 ):

  • Sie erstellen eine benutzerdefinierte ListView, die nicht scrollbar ist

    public class NonScrollListView extends ListView {
    
            public NonScrollListView(Context context) {
                super(context);
            }
            public NonScrollListView(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
            public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
            }
            @Override
            public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int heightMeasureSpec_custom = View.MeasureSpec.makeMeasureSpec(
                        Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
                super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
                ViewGroup.LayoutParams params = getLayoutParams();
                params.height = getMeasuredHeight();
            }
        }
    
  • In Ihrer Layoutdatei

    <ScrollView 
     xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:fillViewport="true">
    
        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content" >
    
            <!-- com.Example Changed with your Package name -->
    
            <com.thedeveloperworldisyours.view.NonScrollListView
                Android:id="@+id/lv_nonscroll_list"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" >
            </com.thedeveloperworldisyours.view.NonScrollListView>
    
            <RelativeLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_below="@+id/lv_nonscroll_list" >
    
                <!-- Your another layout in scroll view -->
    
            </RelativeLayout>
        </RelativeLayout>
    
    </ScrollView>
    
  • Erstellen Sie ein Objekt Ihrer benutzerdefiniertenListview anstelle von ListView wie folgt:

     NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);
    

Stecken Sie NIEMALS eine ListView in eine ScrollView! Weitere Informationen zu diesem Thema finden Sie unter Google . Verwenden Sie in Ihrem Fall LinearLayout anstelle von ListView und fügen Sie die Elemente programmgesteuert hinzu.

1
SimonSays

Rufen Sie diese Funktion einfach auf, nachdem Sie der Listenansicht den Adapter zugewiesen haben 

public static void setListViewHeightBasedOnChildren
            (ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) return;

        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                View.MeasureSpec.UNSPECIFIED);
        int totalHeight = 0;
        View view = null;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            view = listAdapter.getView(i, view, listView);
            if (i == 0) view.setLayoutParams(new
                    ViewGroup.LayoutParams(desiredWidth,
                    ViewGroup.LayoutParams.WRAP_CONTENT));

            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();

        params.height = totalHeight + (listView.getDividerHeight() *
                (listAdapter.getCount() - 1));

        listView.setLayoutParams(params);
        listView.requestLayout();
    } 
0
  • Es ist nicht möglich, die Bildlaufansicht in der Listenansicht zu verwenden, da die Listenansicht bereits über eine Bildlaufeigenschaft verfügt.
  • Um die Listenansicht in der Scroll-Ansicht zu verwenden, können Sie die folgenden Schritte ausführen, die für mich funktioniert haben:

    1) Erstellen Sie eine NonScrollListView Java-Datei, die die standardmäßige Scrolleigenschaft der Listenansicht deaktiviert. und Code ist unten

    package your-package-structure;
    
    import Android.content.Context;
    import Android.util.AttributeSet;
    import Android.view.ViewGroup;
    import Android.widget.ListView;
    
    public class NonScrollListView extends ListView {
    
      public NonScrollListView(Context context) {
          super(context);
      }
      public NonScrollListView(Context context, AttributeSet attrs) {
          super(context, attrs);
      }
      public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
          super(context, attrs, defStyle);
      }
      @Override
      public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
      }
    }
    

    2) Erstellen Sie nun eine XML-Datei mit NestedScrollView und verwenden Sie NonScrollListView für die Auflistung Ihrer Artikel. Dadurch wird der gesamte Bildschirm mit allen Ansichten verschoben.

     

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_weight="1"
                Android:orientation="vertical">
                <ViewFlipper
    
                    Android:id="@+id/v_flipper"
                    Android:layout_width="match_parent"
                    Android:layout_height="130dp">
                </ViewFlipper>
                <TextView
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
    
                    Android:text="SHOP"
                    Android:textSize="15dp"
                    Android:textStyle="bold"
                    Android:gravity="center"
                    Android:padding="5dp"
                    Android:layout_marginTop="15dp"
                    Android:layout_marginBottom="5dp"
                    Android:layout_marginLeft="8dp"
                    Android:layout_marginRight="8dp"/>
                <View
                    Android:layout_width="match_parent"
                    Android:layout_height="1dp"
    
                    Android:layout_marginBottom="8dp"
                    Android:layout_marginLeft="8dp"
                    Android:layout_marginRight="8dp"
                    Android:background="#ddd"/>
            </LinearLayout>
            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:orientation="vertical"
                Android:layout_weight="1"
                >
                <com.abc.xyz.NonScrollListView
                    Android:id="@+id/listview"
    
                    Android:divider="@null"
                    Android:layout_width="match_parent"
                    Android:layout_marginBottom="10dp"
                    Android:layout_height="match_parent"
                    Android:padding="8dp">
                </com.abc.xyz.NonScrollListView>
            </LinearLayout>
    
           <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
    
                Android:gravity="bottom">
                <include layout="@layout/footer" />
            </LinearLayout>
    
        </LinearLayout>
    

     

    3) Jetzt in der Java-Klasse, dh home.Java, definieren Sie NonScrollListView anstelle von Listview.

    package comabc.xyz.landscapeapp;
    import Android.content.Intent;
    import Android.support.annotation.NonNull;
    import Android.support.annotation.Nullable;
    import Android.support.v4.app.Fragment;
    import Android.os.Bundle;
    import Android.support.v4.app.FragmentTransaction;
    import Android.util.Log;
    import Android.view.LayoutInflater;
    import Android.view.View;
    import Android.view.ViewGroup;
    import Android.widget.AdapterView;
    import Android.widget.Button;
    import Android.widget.ImageView;
    
    import Android.widget.ListView;
    import Android.widget.Toast;
    import Android.widget.Toolbar;
    import Android.widget.ViewFlipper;
    

    public class home erweitert Fragment { int pos = 0; ViewFlipper v_flipper;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_home, container, false);
        return view;
    }
    
    @Override
    public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
        NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
        customAdapter customAdapter = new customAdapter(getActivity());
        listView.setAdapter(customAdapter);
        listView.setFocusable(false);
    
        customAdapter.notifyDataSetChanged();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("listview click", "onItemClick: ");
               /* FragmentTransaction fr = getFragmentManager().beginTransaction().replace(R.id.fragment_container, new productdisplay());
    
                fr.putExtra("Position", position);
                fr.addToBackStack("tag");
                fr.commit();*/
                Intent intent = new Intent(getActivity(), productdisplay.class);
                intent.putExtra("Position", position);
                startActivity(intent);
            }
        });
    
    
        //image slider
        int images[] = {R.drawable.slide1, R.drawable.slide2, R.drawable.slide3};
        v_flipper = view.findViewById(R.id.v_flipper);
        for (int image : images) {
            flipperImages(image);
    
        }
    }
    
    private void flipperImages(int image) {
        ImageView imageView = new ImageView(getActivity());
        imageView.setBackgroundResource(image);
    
        v_flipper.addView(imageView);
        v_flipper.setFlipInterval(4000);
        v_flipper.setAutoStart(true);
    
        v_flipper.setInAnimation(getActivity(), Android.R.anim.slide_in_left);
        v_flipper.setOutAnimation(getActivity(), Android.R.anim.slide_out_right);
    }
    }
    

    Hinweis: Ich habe hier Fragments verwendet.

0
user8235005

Legen Sie einfach den Wert der erforderlichen Höhe in einem Listenansicht-Höhenattribut in einer übergeordneten Bildlaufansicht fest. Es wird zusammen mit den untergeordneten Elementen anderer Eltern angezeigt.

0
Shibu Tamang