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