简体   繁体   English

android listview显示所有可用项目,无需滚动静态标题

[英]android listview display all available items without scroll with static header

I'm having a little difficulties while trying to get a certain layout to work: I want to have list.我在尝试使某个布局起作用时遇到了一些困难:我想要列表。 List does not have to be scrollable, but should be shown completely.列表不必可滚动,但应完整显示。 But the page itself should be able to scroll (with the lists in it), if the total content ist higher than the screen.但是如果总内容高于屏幕,页面本身应该能够滚动(其中包含列表)。

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

it only uses a small part of the screen (about 2 lines per list), instead of filling the available height, and the lists themselves can be scrolled.它只使用屏幕的一小部分(每个列表大约 2 行),而不是填充可用高度,并且列表本身可以滚动。 How can I change the layout to always show the whole lists but have the screen be scrollalbe?如何更改布局以始终显示整个列表但让屏幕滚动?

The solution I used is to replace ListView with LinearLayout.我使用的解决方案是用 LinearLayout 替换 ListView。 You can create all your items inside LinearLayout, they will all be displayed.您可以在 LinearLayout 中创建所有项目,它们都会显示出来。 So there's really no need to use ListView.所以真的没有必要使用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);
}

As @Alex noted in the accepted answer that LinearLayout is hardly a replacement.正如@Alex 在接受的答案中指出的,LinearLayout 几乎不是替代品。 I had a problem where LinearLayout was not an option, that's when i came across this blog .我遇到了一个问题,即 LinearLayout 不是一个选项,那是我遇到这个博客的时候 I will put the code here for reference purposes.我将代码放在这里以供参考。 Hope it helps someone out there!希望它可以帮助那里的人!

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

    }
}

Usage:用法:

//initializing the adapter
listView.setAdapter(adapter);
UIUtils.setListViewHeightBasedOnItems(listView);

//whenever the data changes
adapter.notifyDataSetChanged();
UIUtils.setListViewHeightBasedOnItems(listView);

You can make your own customlistview.您可以制作自己的自定义列表视图。 (It can extends ListView/ExpandableListView/GridView) and override the onMeasure method with this. (它可以扩展 ListView/ExpandableListView/GridView)并用它覆盖 onMeasure 方法。 With this you'll never need to call a function or anything.有了这个,您将永远不需要调用函数或任何东西。 Just use it in your xml.只需在您的 xml 中使用它。

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
            MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
}

I had a ListView in my layout and wanted to use a library which can't handle a ListView here because it wraps it into a ScrollView .我的布局中有一个ListView并想使用一个无法处理ListView的库,因为它将它包装成一个ScrollView The best solution for me is based on Fedor´s answer.对我来说最好的解决方案是基于 Fedor 的回答。

Since I already got an ArrayAdapter for the ListView I wanted to re-use it:由于我已经为ListView获得了一个ArrayAdapter ,因此我想重新使用它:

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

For me this works fine because I just need to display dynamic data varying from 1 to 5 elements.对我来说这很好用,因为我只需要显示从 1 到 5 个元素变化的动态数据。 I just had to add my own divider.我只需要添加我自己的分隔线。

If someone still has the problem then you can make customList and add onMesure() method just like I implemented it:如果有人仍然有问题,那么您可以制作 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);
}
}

I just did it using setting params of ListView我只是使用 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);  
}

Check this out:看一下这个:

ListView ignoring wrap_content ListView 忽略 wrap_content

Using android:layout_height and android:layout_weight solved it for me:使用 android:layout_height 和 android:layout_weight 为我解决了这个问题:

<ListView
    android:layout_height="0dp"
    android:layout_weight="1"
    />

If all items has the same height如果所有项目具有相同的高度

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

Iam supprised no one see this.U cant have two scrolls on the same layout.我很惊讶没有人看到这个。你不能在同一个布局上有两个卷轴。 1st u have a scrollview and then u have a list, i bet u are killing some android good practices there.首先你有一个滚动视图,然后你有一个列表,我敢打赌你在那里杀死了一些 android 良好实践。

If you want a simple solution to this problem without extending ListView class, this is a solution for you.如果您想在不扩展 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);
        }
    });

I don't have a static header, but using HussoM's post as a clue, here is what I was able to get to work.我没有静态标题,但使用 HussoM 的帖子作为线索,这是我能够开始工作的内容。 In my scenario, the height of the items in the list was non-uniform, due to variable text sentences in each of the items, and I am using wrap_content for the height and match_parent for the width.在我的场景中,由于每个项目中的文本句子可变,因此列表中项目的高度不均匀,我使用 wrap_content 作为高度,使用 match_parent 作为宽度。

public class NonScrollableListView extends ListView {

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

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

  public NonScrollableListView(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
  }

  public NonScrollableListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
  }

  /**
   * Measure the height of all the items in the list and set that to be the height of this
   * view, so it appears as full size and doesn't need to scroll.
   * @param widthMeasureSpec
   * @param heightMeasureSpec
   */
  @Override
  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      ListAdapter adapter = this.getAdapter();
      if (adapter == null) {
          // we don't have an adapter yet, so probably initializing.
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          return;
      }

      int totalHeight = 0;

      // compute the height of all the items
      int itemCount = adapter.getCount();
      for (int index=0; index<itemCount; index++) {
          View item = adapter.getView(index, null, this);
          // set the width so it can figure out the height
          item.measure(widthMeasureSpec, 0);
          totalHeight += item.getMeasuredHeight();
      }

      // add any dividers to the height
      if (this.getDividerHeight() > 0) {
          totalHeight += this.getDividerHeight() * Math.max(0, itemCount - 1);
      }

      // make it so
      this.setMeasuredDimension(widthMeasureSpec,
              MeasureSpec.makeMeasureSpec(totalHeight, MeasureSpec.EXACTLY));
  }

} }

In my case, I had ListView inside ScrollView and scrollview was shrinking listview by default.就我而言,我在ScrollViewListView并且默认情况下ScrollView视图正在缩小列表视图。 So I just add this in my ScrollView and it worked for me所以我只是将它添加到我的ScrollView ,它对我ScrollView

android:fillViewport="true"

在你的 LinearLayout 中设置android:layout_height="fill_parent"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM