Tampilan daftar Android di dalam tampilan gulir


268

Saya memiliki tata letak android yang memiliki scrollViewsejumlah elemen di dalamnya. Di bagian bawah scrollViewsaya punya listViewyang kemudian diisi oleh adaptor.

Masalah yang saya alami, adalah android tidak termasuk listViewdari scrollViewyang scrollViewsudah memiliki fungsi scroll-mampu. Saya ingin listViewmenjadi selama konten dan untuk tampilan master gulir agar dapat gulir.

Bagaimana saya bisa mencapai perilaku ini?

Inilah tata letak utama saya:

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

Saya kemudian pemrograman menambahkan komponen saya ke linearlayour dengan id: foodItemActvity_linearLayout_fragments. Di bawah ini adalah salah satu tampilan yang dimuat ke linearlayout itu. Ini yang memberiku masalah dengan gulungan.

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

Adaptor saya kemudian mengisi tampilan daftar ini.

Berikut adalah gambar dari penampil hierarki android ketika saya mengklik master scrollView:

Tampilan Daftar Android di dalam tampilan gulir

Seperti yang Anda lihat, tidak termasuk listView ulasan.

Saya harus dapat menggulir halaman ke bawah dan melihat 8 ulasan, tetapi sebaliknya itu hanya menunjukkan kepada saya 3, dan saya dapat menggulir pada bagian kecil di mana ulasan berada. Saya ingin gulir halaman global



saya mendapatkan solusinya di: androidhub4you.com/2012/12/…
Md Imran Choudhury

Ini dia. Anda dapat menemukan informasi deskriptif lengkap: stackoverflow.com/questions/20116381/…
Farruh Habibullaev

Ini sangat mudah menggunakan nama RecycleView ListView
Anand Raj Mehta

saya harap ini akan berhasil untuk Anda stackoverflow.com/a/62011087/11554604
S Kumar

Jawaban:


559

Solusi terpendek & termudah untuk ChildView untuk menggulir di dalam ScrollView . Apa pun seperti ListView, RecyclerView, dll. Anda tidak perlu melakukan sesuatu yang istimewa dalam kode.

Cukup ganti ScrollView dengan android.support.v4.widget.NestedScrollView di xml Anda saat ini dan kemudian keajaiban terjadi.

Di bawah ini adalah contoh kode xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:paddingBottom="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Recycler View inside a Scroll View"
            android:textColor="@color/black"
            android:textSize="@dimen/_20sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Below is a Recycler View as an example."
            android:textSize="16sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toBottomOf="@id/et_damaged_qty" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="This text automatically goes below the Recycler View."
            android:textSize="16sp" />
    </android.support.v7.widget.LinearLayoutCompat>
</android.support.v4.widget.NestedScrollView>

Sekarang Anda dapat menyingkirkan semua peretasan jelek yang kami lakukan untuk mengatasi pengguliran bersarang ini.

Saatnya bermain. Ya ampun, ya ampun.

masukkan deskripsi gambar di sini


1
@JeetenParmar sudah menentukan masalah ini, sekali lagi saya harus mengatakan - ini adalah hack yang bagus tetapi tidak berfungsi ketika TextView memiliki beberapa baris di dalamnya. Arshu - solusi Anda nanti untuk Jeeten juga tidak berfungsi (Jeeten sudah ditentukan). Jika Anda menemukan solusi untuk ini, silakan posting di sini. Saya sangat membutuhkan solusi.
Khobaib

4
Saya menemukan solusi ini yang berfungsi dengan baik dalam kasus saya, yaitu mendukung item-daftar dengan variabel ketinggian - stackoverflow.com/a/17503823/1433187
Khobaib

3
Harap hapus redundan requestLayout()- metode setLayoutParams sudah melakukannya.
Oleksii Malovanyi

2
Pengukuran FIXview.measure(MeasureSpec.makeMeasureSpec(desiredWidth, MeasureSpec.AT_MOST),MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
Oleksii Malovanyi

2
Saya perlu melakukan hal yang sama dengan gridview .. Ada saran?
Kelinci

223

Jawabannya sederhana dan saya terkejut belum dijawab di sini.

Gunakan a Header Viewatau / dan Footer Viewpada daftar itu sendiri. Jangan mencampur ScrollViewdengan ListViewatau apa pun yang dapat menggulir. Ini dimaksudkan untuk digunakan dengan header dan footer :)

Pada dasarnya, ambil semua konten di atas ListView Anda, letakkan di file .xml lain sebagai tata letak dan kemudian dalam kode kembangkan dan tambahkan ke daftar sebagai tampilan header.

yaitu

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

2
@ericosg, Tapi saya tidak mau ini sebabnya saya mencari solusi.
Jeeten Parmar

13
Jika Anda menambahkan tampilan header, posisi int param di onListItemClick akan menjadi +1. Jadi, Anda harus menanganinya. (item pertama dalam daftar akan memiliki posisi 1, bukan 0)
CoPLaS

Saya berharap ada header untuk ViewPager.
hasan

2
Saya berharap ada tajuk untuk GridView
Seseorang Di suatu tempat

1
pendekatan ini berjalan dengan baik kecuali jika Anda memerlukan edittext di header. Edittext tidak mempertahankan fokus saat hadir dalam
tampilan daftar

41

Saya tahu sudah begitu lama tetapi saya juga mengalami masalah ini, mencoba solusi ini dan berhasil. Jadi saya kira itu dapat membantu yang lain juga.

Saya menambahkan android: fillViewport = "true" pada layout xml untuk scrollView. Jadi secara keseluruhan ScrollView saya akan seperti ini.

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

Dan itu bekerja bagaikan sulap bagiku. ListView yang terletak di dalam ScrollView saya memperluas ke ukurannya lagi.

Berikut adalah contoh kode lengkap untuk ScrollView dan 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>

4
Ini menonaktifkan perilaku pengguliran ListView, oleh karena itu Anda tidak dapat menggulir tampilan daftar Anda jika item lebih dari ukuran layar.
Darush

3
Ini menonaktifkan kemampuan gulir dari ScrollView
Pranav Mahajan

24

Anda Membuat Custom ListView yang bukan dapat digulir

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

Di File Sumber Daya Tata Letak Anda

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

Dalam Java File, Buat objek customListview Anda, bukan ListView seperti: NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);


atau Anda dapat membagikan tautannya saja
miracle-doh

Ini memaksa scrollview untuk menggulir di bagian atas listview. perilaku tak terduga
Bhavik Mehta

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

Anda dapat menggunakan kode ini untuk tampilan daftar di tampilan layar gulir


Apakah itu akan menonaktifkan scroll Listviews dibangun?
Zapnologica

Ini juga akan berfungsi untuk ListViewdi dalam RecyclerViewuntuk menampilkan lebih dari 1 elemen.
sandalone

8

Anda dapat menyelesaikannya dengan menambahkan android:fillViewport="true"ke ScrollView Anda.

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


sebelum menggunakan properti itu, hanya ada satu anak dari tampilan daftar saya yang terlihat. setelah menggunakan itu semua baris atau anak daftar terlihat.


Android: scrollingCache = "false" tidak lagi didukung untuk versi Android baru di atas v8.
Teluk

7

Jangan lakukan apa pun di Parent ScrollView. Hanya lakukan ini pada ListView anak. Semuanya akan bekerja dengan sempurna.

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

2
Ini harus menjadi jawaban yang diterima. Sederhana dan cerdas. Cukup nonaktifkan scrollview ketika Anda menyentuh listiview dan aktifkan lagi ketika Anda mengangkat jari Anda
Yunus Kulyyev

Bekerja dengan sempurna. Semoga orang lain gulir ke bawah ke jawaban ini juga!
Kunj Mehta

6

Kode ini akan menyelesaikan masalah Anda jika Anda hanya menerapkan ListView dalam kode.

Jika Anda menggunakan RelativeLayout sebagai anak ListView daripada kode ini, kembalikan NullPointerException di sini listItem.measure (0, 0); , karena RelativeLayout. Dan solusinya adalah meletakkan Relativelayout Anda di dalam LinearLayout dan itu akan berfungsi dengan baik.

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

Jika Anda memiliki padding di listview Anda maka Anda harus menambahkannya juga: - int padding = listView.getPaddingTop () + listView.getPaddingBottom ();
David

Ya, tata letak relatif menciptakan masalah saat menghitung ketinggian. Terima kasih telah menjelaskan masalah tata letak relatif
Anil Ravsaheb Ghodake

5

Saya akan meninggalkannya di sini kalau-kalau ada yang akan menghadapi masalah yang sama. Saya harus meletakkan ListView di dalam ScrollView. ListView dengan header bukan opsi karena sejumlah alasan. Tidak ada pilihan untuk menggunakan LinearLayout, bukan ListView. Jadi saya mengikuti solusi yang diterima, tetapi tidak berhasil karena item dalam daftar memiliki tata letak yang kompleks dengan beberapa baris dan setiap item tampilan daftar memiliki ketinggian variabel. Ketinggian diukur tidak dengan benar. Solusinya adalah mengukur setiap item di dalam metode getView () ListView Adapter.

@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

Anda dapat dengan mudah memasukkan ListView di ScrollView! Hanya perlu mengubah ketinggian ListView secara pemrograman , seperti ini:

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

Ini bekerja dengan sempurna!


3
Itulah yang dilakukan jawaban yang diterima tetapi alih-alih secara ajaib menentukan itu 400, itu menghitung ketinggian yang tepat. Dengan begitu Anda tidak perlu menebak.
Jeroen Vannevel

Apa maksudmu sihir "persis tinggi"? Yang persis tinggi harus, hanya pengembang yang akan memilih - 400px, atau setengah layar. Pokoknya jika Anda perlu mendapatkan ListView dalam layar penuh, ada banyak cara mudah untuk mendapatkan ketinggian, hanya untuk menghitung ketinggian layar melalui DisplayMetrics, dan menempatkan nomor ini pada ketinggian ListView. XD
Taras Okunev

4

Dilakukan setelah banyak R&D:

fragment_one.xml akan terlihat seperti:

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

Kelas Java Anda dari FragmentOne.java terlihat seperti:

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

Saya memiliki masalah yang mirip dengan masalah yang ditimbulkan oleh Poster Asli - bagaimana membuat scroll listview di dalam scrollview - dan jawaban ini memecahkan masalah saya. Nonaktifkan pengguliran ListView yang ada di dalam ScrollView

Saya tidak menyebut fragmen baru ke layout yang ada atau semacamnya, seperti yang dilakukan OP, jadi kode saya akan terlihat seperti ini:

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

Pada dasarnya apa yang saya lakukan adalah memeriksa panjang tampilan daftar sebelum saya menyebutnya dan ketika saya menyebutnya saya membuatnya menjadi panjang itu. Di kelas java Anda gunakan fungsi ini:

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

Dan panggil fungsi seperti ini:

justifyListViewHeightBasedOnChildren(listView);

Hasilnya adalah tampilan daftar tanpa bilah gulir, seluruh panjang tampilan daftar yang ditampilkan, yang menggulir dengan bilah gulir tampilan scroll.


3

Seperti yang telah disebutkan orang lain, jangan gunakan ListView di dalam ScrollView.

Untuk mengatasinya, Anda dapat menggunakan LinearLayout, tetapi untuk menjaga semuanya tetap rapi - isi LinearLayout Anda dengan Adaptor, sama seperti yang Anda lakukan dengan ListView

Anda dapat menggunakan kelas ini sebagai pengganti LinearLayout yang mendukung Adaptor

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

apakah ini mengelola daur ulang? atau apakah adaptor yang bertanggung jawab untuk tampilan daur ulang?
René M

Saya menerapkan kelas ini beberapa waktu lalu, jadi saya pikir untuk tujuan dev.speed saya tidak menambahkan dukungan daur ulang. Seperti yang saya lihat dalam kode sekarang kelas mengasumsikan bahwa pendaur ulang itu kosong
AAverin

3

Anda bisa meletakkan semuanya ke tata letak linier. Yaitu, buat tata letak linier dan itu akan memiliki 2 anak, scrollview dan tata letak linier lainnya. Beri mereka bobot tata letak dan ini dia:

<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

Anda seharusnya tidak pernah menggunakan ScrollView dengan ListView, karena ListView menangani pengguliran vertikalnya sendiri. Yang paling penting, melakukan ini mengalahkan semua optimasi penting di ListView untuk berurusan dengan daftar besar, karena itu secara efektif memaksa ListView untuk menampilkan seluruh daftar itemnya untuk mengisi wadah tak terbatas yang disediakan oleh ScrollView.

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


3

Persyaratan saya adalah memasukkan ListView dari item berukuran sama di dalam ScrollView. Saya mencoba beberapa solusi lain yang tercantum di sini, sepertinya tidak ada yang mengukur ukuran ListView dengan benar (terlalu sedikit ruang atau terlalu banyak). Inilah yang bekerja untuk saya:

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

Semoga ini bisa membantu seseorang.


2

Jangan pernah memasukkan bagian ListViewdalam ScrollView! Anda dapat menemukan informasi lebih lanjut tentang topik itu di Google . Dalam kasus Anda, gunakan a LinearLayoutbukan ListViewdan tambahkan elemen secara terprogram.


3
Oh Ok, begitu, bisakah saya menggunakan konsep adaptor yang serupa untuk mengisi linearlayout?
Zapnologica

2

Memperbarui

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

untuk

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

Intinya di sini adalah Anda mencoba mengatur ketinggian ke 0dp (tetap)


Itu adalah agar bobot berpengaruh padanya.
Zapnologica

Apakah Anda ingin gambar produk dan tampilan teks kiri di sisi atas dapat digulir? Jika demikian, Anda harus mengeluarkan dua item ini di dalam tampilan Gulir Anda seperti yang saya lihat saat ini tidak
Rajnish Mishra

Mereka saat ini berada di dalam scrollView ketika saya secara terprogram menambahkannya ke tata letak linier yang ada di dalam scrollview. Jika logika saya benar, anak-anak linearlayout juga harus menggunakan scrollview.
Zapnologica

2

menemukan solusi untuk scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> listview dinamis, tetapi saya bukan penulisnya. ada beberapa bug, tetapi setidaknya itu berfungsi

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

tata letak fragmen bisa apa saja

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

lalu di suatu tempat saja

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
  • Tidak mungkin menggunakan tampilan Gulir di dalam Tampilan daftar karena Tampilan daftar sudah memiliki properti gulir.
  • Untuk menggunakan tampilan daftar di dalam Tampilan gulir, Anda dapat mengikuti langkah-langkah ini yang berfungsi untuk saya:

    1) Buat file java NonScrollListView yang menonaktifkan properti gulir default tampilan-daftar. dan kode di bawah ini

    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) Sekarang buat file xml yang memiliki NestedScrollViewdan di dalamnya digunakan NonScrollListViewuntuk daftar item Anda. Ini akan membuat seluruh layar Anda menggulir dengan semua tampilan.

            <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) Sekarang di kelas java yaitu, home.java mendefinisikan NonScrollListViewbukan 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;

    home class public memperpanjang 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);
    }
    }

    Catatan: Saya digunakan di Fragmentssini.


1

Ok, ini jawaban saya. Metode yang memperbaiki ketinggian ListView cukup tertutup, tetapi tidak sempurna. Jika sebagian besar barang memiliki ketinggian yang sama, itu berfungsi dengan baik. Tetapi jika itu tidak terjadi, maka ada masalah besar. Saya sudah mencoba banyak waktu, dan ketika saya mengeluarkan nilai listItem.getMeasureHeight dan listItem.getMeasuerWidth ke dalam log, saya melihat nilai lebar sangat bervariasi, yang tidak diharapkan di sini, karena semua item dalam ListView yang sama harus memiliki lebar yang sama. Dan itu dia bug:

Beberapa menggunakan ukuran (0, 0), yang sebenarnya membuat tampilan tidak terikat, di kedua arah, dan lebar menjadi liar. Beberapa mencoba mendapatkan Lebar listView, tetapi kemudian mengembalikan 0, tidak berarti.

Ketika saya membaca lebih lanjut tentang bagaimana Android membuat Tampilan, saya menyadari bahwa semua upaya ini tidak dapat mencapai jawaban yang saya cari, kecuali fungsi ini berjalan setelah tampilan di-render.

Kali ini saya menggunakan getViewTreeObserver pada ListView yang ingin saya perbaiki ketinggiannya, kemudian tambahkan OnGlobalLayoutListener. Di dalam metode ini, saya mendeklarasikan OnGlobalLayoutListener baru, di mana, kali ini, getWidth mengembalikan lebar sebenarnya dari ListView.

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

Value pad, adalah padding yang saya atur di layout ListView.


1

Jika karena alasan tertentu Anda tidak ingin menggunakan addHeaderViewdan addFooterView, misalnya ketika Anda memiliki beberapa daftar, ide yang baik adalah menggunakan kembali ListAdapteruntuk mengisi sederhana LinearLayoutsehingga tidak ada fungsi gulir.

Jika Anda sudah memiliki seluruh fragmen yang berasal dari ListFragmentdan ingin mengonversinya menjadi fragmen yang sama dengan yang sederhana LinearLayouttanpa menggulir sebagai gantinya (misalnya untuk meletakkannya di ScrollView), Anda dapat menerapkan fragmen adaptor seperti ini:

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

Anda juga mungkin ingin meneruskan onCreate, onPause, onResume, dll untuk fragmen asli tergantung pada kebutuhan Anda atau mencoba warisan bukan komposisi (tapi menimpa metode tertentu sehingga fragmen asli tidak benar-benar melekat hirarki tata letak); tapi saya ingin mengisolasi fragmen asli sebanyak mungkin, karena kita hanya perlu mengekstraknya ListAdapter. Jika Anda menghubungi fragmen asli setListAdapterdi onAttach, itu mungkin cukup.

Berikut cara menggunakannya ListAsArrayFragmentuntuk memasukkan OriginalListFragmenttanpa menggulir. Dalam aktivitas induk onCreate:

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

menemukan solusi untuk scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> listview dinamis, tetapi saya bukan penulisnya.

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

tata letak fragmen bisa apa saja

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

lalu di suatu tempat saja

 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

menggunakan ListView ini. Bekerja untuk saya

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

dan dalam xml

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

dan di MainActivity

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

Lihat artikel ini untuk info lebih lanjut dan juga untuk mengetahui cara menjaga tampilan gridview di dalam gulir


1

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

Di Jawa:

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

0

Cukup atur nilai tinggi yang diperlukan dalam atribut ketinggian tampilan daftar di dalam layar induk. Ini akan bergulir bersama dengan item anak orang tua lainnya.


0

Ini bekerja untuk saya ( link1 , link2 ):

  • Anda Membuat Custom ListView yang bukan dapat digulir

    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();
            }
        }
  • Di File Layout Anda

    <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>
  • Buat objek dari customListview Anda alih-alih ListView seperti:

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

0

Panggil saja fungsi ini setelah menetapkan adaptor ke listview

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

-1
listView.setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
    scrollView.requestDisallowInterceptTouchEvent(true);

    int action = event.getActionMasked();

    switch (action) {
        case MotionEvent.ACTION_UP:
            scrollView.requestDisallowInterceptTouchEvent(false);
            break;
    }

    return false;
}
});

-1

Kode terbaik

 <android.support.v4.widget.NestedScrollView
    android:id="@+id/scrollView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/btmlyt"
    android:layout_below="@+id/deshead_tv">

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

    <TextView
        android:id="@+id/des_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/btmlyt"
        android:background="@android:color/white"
        android:paddingLeft="3dp"
        android:paddingRight="3dp"
        android:scrollbars="vertical"
        android:paddingTop="3dp"
        android:text="description"
        android:textColor="@android:color/black"
        android:textSize="18sp" />
    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.