Android listview отображает все доступные элементы без прокрутки со статическим заголовком
У меня возникают небольшие трудности при попытке получить определенный макет: я хочу иметь список. Список не должен быть прокручиваемым, но должен быть показан полностью. Но сама страница должна иметь возможность прокручивать (со списками в ней), если общий контент ist выше экрана.
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#ff181818"
>
<Textview android:id="@+id/my_text" text="header contents goes here" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<Textview android:id="@+id/headertext" text="header contents goes here" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<ListView
android:id="@+id/my_list1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
</LinearLayout>
</ScrollView>
он использует только небольшую часть экрана (около 2 строк в списке) вместо заполнения доступной высоты, а сами списки можно прокручивать. Как я могу изменить макет, чтобы всегда показывать все списки, но иметь экран прокрутки?
Ответы
Ответ 1
Решение, которое я использовал, заключается в замене ListView на LinearLayout. Вы можете создать все свои элементы внутри LinearLayout, все они будут отображаться. Поэтому нет необходимости использовать ListView.
LinearLayout list = (LinearLayout)findViewById(R.id.list_recycled_parts);
for (int i=0; i<products.size(); i++) {
Product product = products.get(i);
View vi = inflater.inflate(R.layout.product_item, null);
list.addView(vi);
}
Ответ 2
Как @Alex отметил в принятом ответе, что LinearLayout вряд ли заменяет. У меня была проблема, когда LinearLayout не был вариантом, когда я столкнулся с этим blog. Я поставлю код здесь для справки. Надеюсь, это поможет кому-то там!
public class UIUtils {
/**
* Sets ListView height dynamically based on the height of the items.
*
* @param listView to be resized
* @return true if the listView is successfully resized, false otherwise
*/
public static boolean setListViewHeightBasedOnItems(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
item.measure(0, 0);
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
}
Использование:
//initializing the adapter
listView.setAdapter(adapter);
UIUtils.setListViewHeightBasedOnItems(listView);
//whenever the data changes
adapter.notifyDataSetChanged();
UIUtils.setListViewHeightBasedOnItems(listView);
Ответ 3
У меня был ListView
в моем макете и я хотел использовать библиотеку, которая не может обрабатывать ListView
здесь, потому что она переносит ее в ScrollView
. Лучшее решение для меня основано на ответе Федора.
Поскольку у меня уже есть ArrayAdapter
для ListView
, я хотел его повторно использовать:
LinearLayout listViewReplacement = (LinearLayout) findViewById(R.id.listViewReplacement);
NamesRowItemAdapter adapter = new NamesRowItemAdapter(this, namesInList);
for (int i = 0; i < adapter.getCount(); i++) {
View view = adapter.getView(i, null, listViewReplacement);
listViewReplacement.addView(view);
}
Для меня это отлично работает, потому что мне просто нужно отображать динамические данные, варьирующиеся от 1 до 5 элементов. Мне просто пришлось добавить свой собственный разделитель.
Ответ 4
Вы можете создать свой собственный профиль. (Он может расширять ListView/ExpandableListView/GridView) и переопределять метод onMeasure с этим. С этим вам никогда не нужно будет вызывать функцию или что-то еще. Просто используйте его в своем xml.
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
Ответ 5
Проверьте это:
ListView игнорирует wrap_content
Использование android: layout_height и android: layout_weight решили это для меня:
<ListView
android:layout_height="0dp"
android:layout_weight="1"
/>
Ответ 6
Я просто сделал это, используя настройки параметров ListView
public static void setListViewHeightBasedOnChildren(ListView listView) {
//this comes from value from xml tag of each item
final int HEIGHT_LARGE=75;
final int HEIGHT_LARGE=50;
final int HEIGHT_LARGE=35;
ViewGroup.LayoutParams params = listView.getLayoutParams();
int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
switch(screenSize) {
case Configuration.SCREENLAYOUT_SIZE_LARGE:
params.height =(int) (HEIGHT_LARGE*size);
break;
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
params.height =(int) (HEIGHT_NORMAL*size);
break;
case Configuration.SCREENLAYOUT_SIZE_SMALL:
params.height =(int) (HEIGHT_SMALL*size);
break;
}
listView.setLayoutParams(params);
}
Ответ 7
Если у кого-то еще есть проблема, вы можете сделать customList и добавить метод onMesure()
, как я его реализовал:
public class ScrolleDisabledListView extends ListView {
private int mPosition;
public ScrolleDisabledListView(Context context) {
super(context);
}
public ScrolleDisabledListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrolleDisabledListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Record the position the list the touch landed on
mPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
return super.dispatchTouchEvent(ev);
}
if (actionMasked == MotionEvent.ACTION_MOVE) {
// Ignore move events
return true;
}
if (actionMasked == MotionEvent.ACTION_UP) {
// Check if we are still within the same view
if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) {
super.dispatchTouchEvent(ev);
} else {
// Clear pressed state, cancel the action
setPressed(false);
invalidate();
return true;
}
}
return super.dispatchTouchEvent(ev);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Ответ 8
Если все элементы имеют одинаковую высоту
int totalItemsHeight = baseDictionaries.size() * item.getMeasuredHeight();
int totalDividersHeight = listView.getDividerHeight() * (baseDictionaries.size() - 1);
int totalPadding = listView.getPaddingBottom() + listView.getPaddingTop();
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) listTranslationWords.getLayoutParams();
lp.height = totalItemsHeight + totalDividersHeight + totalPadding;
listTranslationWords.setLayoutParams(lp);
Ответ 9
Я думаю, что никто не видит этого. У вас нет двух свитков на одном макете. 1-й у вас есть scrollview, а затем у вас есть список, я уверен, что вы убиваете некоторые хорошие практики в android.
Ответ 10
Если вы хотите простое решение этой проблемы без расширения класса ListView, это решение для вас.
mListView.post(new Runnable() {
@Override
public void run() {
int height = 0;
for(int i = 0; i < mListView.getChildCount();i++)
height += mListView.getChildAt(i).getHeight();
ViewGroup.LayoutParams lParams = mListView.getLayoutParams();
lParams.height = height;
mListView.setLayoutParams(lParams);
}
});
Ответ 11
Установите android:layout_height="fill_parent"
в LinearLayout