ListView控件中的滚动型 - 小bug控件、ListView、bug

2023-09-04 23:40:34 作者:迷入感情路

我想在滚动视图列表视图。这种方法是做什么的近乎完美: http://stackoverflow.com/a/3495908/2811653

有一个错误,当我在一行中输入一列文本超出:

1: http://abload.de/img/screenshot_2013-10-311jq5t。 JPG

2: http://abload.de/img/screenshot_2013-10-31lvrad。 JPG

向下滚动到按钮工作正常,但因为你的第二个屏幕看到P不正确显示: - (

在实用工具类的高度,不计算正确,当我填写列表视图的第一行这样的。

有谁知道如何解决它?

(提示:主要的一点是,我要滚动至列表视图下方的按钮,我不希望按钮总是被显示出来(所以没有重量= 1))

code:

 包com.example.tmpapplication;

进口android.app.ListActivity;
进口android.os.Bundle;
进口android.view.Menu;
进口android.view.View;
进口android.view.ViewGroup;
进口android.widget.ArrayAdapter;
进口android.widget.ListAdapter;
进口android.widget.ListView;

公共类MainActivity扩展ListActivity {

静态最终的String []数据=新的String []
{
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
        的B,
        C,
        D,
        E,
        F,
        G,
        H,
        一世,
        J,
        K,
        的L,
        M,
        N
        O,
        P
};

@覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);
    setListAdapter(新ArrayAdapter<字符串>(这一点,R.layout.list,数据));

    ListView控件的ListView =(ListView控件)findViewById(android.R.id.list);
    Utility.setListViewHeightBasedOnChildren(ListView控件);
}


@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    //充气菜单;这增加了项目操作栏,如果它是present。
    。getMenuInflater()膨胀(R.menu.main,菜单);
    返回true;
}
}

类工具{
公共静态无效setListViewHeightBasedOnChildren(ListView控件的ListView){
    ListAdapter listAdapter = listView.getAdapter();
    如果(listAdapter == NULL){
        // pre-条件
        返回;
    }

    INT totalHeight = 0;
    的for(int i = 0; I< listAdapter.getCount();我++){
        查看的listItem = listAdapter.getView(I,空,ListView控件);
        listItem.measure(0,0);
        totalHeight + = listItem.getMeasuredHeight();
    }

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

XML: activity_main.xml

 <滚动型的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
机器人:layout_width =match_parent
机器人:layout_height =match_parent
>
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:以下属性来=@扪/ activity_horizo​​ntal_margin
机器人:paddingRight =@扪/ activity_horizo​​ntal_margin
机器人:paddingTop =@扪/ activity_vertical_margin
机器人:paddingBottom会=@扪/ activity_vertical_margin
工具:上下文=。MainActivity
机器人:方向=垂直
>

<的ListView
    机器人:ID =@机器人:ID /列表
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT>
< / ListView控件>

<按钮
    机器人:ID =@ + ID /按钮
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=按钮
    >
< /按钮>
 
VB小程序问题,ListView控件

list.xml:

 < XML版本=1.0编码=UTF-8&GT?;

< TextView中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=文本
    机器人:填充=10dp
    机器人:TEXTSIZE =20SP
/>
 

解决方案

试试这个方案,我发布here.

如果你不希望自己的ListView滚动,只是想ListView的高度是这样的,所有的元素都显示,那么你可以创建ListView控件的子类来实现这一点。

 公共类ListViewForEmbeddingInScrollView扩展的ListView {
    公共ListViewForEmbeddingInScrollView(上下文的背景下){
        超(上下文);
    }

    公共ListViewForEmbeddingInScrollView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
    }

    公共ListViewForEmbeddingInScrollView(上下文的背景下,ATTRS的AttributeSet,诠释defStyleAttr){
        超(背景下,ATTRS,defStyleAttr);
    }

    @覆盖
    保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
        super.onMeasure(widthMeasureSpec,MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE的>→4,MeasureSpec.AT_MOST));
    }
}
 

操纵heightMeasureSpec将具有非常大的尺寸(Integer.MAX_VALUE的>> 4)导致的ListView来衡量所有的孩子直到给定的(非常大)的高度,并相应设置其高度。AT_MOST

有一个关于这个问题的here包括很多讨论,以是否是适当的,即使这样做。我没有足够的信誉来后我的答案,但是这是比任何在该链接的解决方案更好。也许有人有更多的声誉将跨越这个运行并张贴链接回到这一个,其他问题的解决方案。

I'd like to have a listview in scrollview. This method is doing it almost perfect: http://stackoverflow.com/a/3495908/2811653

There is a bug when I enter more text in a row than fits in one line:

1: http://abload.de/img/screenshot_2013-10-311jq5t.jpg

2: http://abload.de/img/screenshot_2013-10-31lvrad.jpg

Scrolling down to the button works fine BUT as you see in the second screenshot the P is not displayed correctly :-(

In the Utility class the height is not calculated correctly when I fill the first row of listview like that.

Does anyone know how to fix it?

(Hint: the main point is that I want to scroll to the button which is below the listview. I don't want the button always to be displayed (so no weight=1))

Code:

package com.example.tmpapplication;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

public class MainActivity extends ListActivity {

static final String[] data=new String[]
{
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
        "B",
        "C",
        "D",
        "E",
        "F",
        "G",
        "H",
        "I",
        "J",
        "K",
        "L",
        "M",
        "N",
        "O",
        "P"
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setListAdapter(new ArrayAdapter<String>(this, R.layout.list, data));

    ListView listView=(ListView) findViewById(android.R.id.list);
    Utility.setListViewHeightBasedOnChildren(listView);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
}

class Utility {
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);
    }
}

XML: activity_main.xml

<ScrollView  xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical"
>

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >
</ListView>

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button"
    >
</Button>

list.xml:

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="text"
    android:padding="10dp"
    android:textSize="20sp"
/>

解决方案

Try this solution that I posted here.

If you do not want the ListView itself to scroll and just want the ListView's height to be such that all elements are shown, then you can create a subclass of ListView to accomplish this.

public class ListViewForEmbeddingInScrollView extends ListView {
    public ListViewForEmbeddingInScrollView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 4, MeasureSpec.AT_MOST));
    }
}

Manipulating the heightMeasureSpec to be AT_MOST with a very large size (Integer.MAX_VALUE >> 4) causes the ListView to measure all of its children up to the given (very large) height and set its height accordingly.

There is much discussion about this problem here including a lot of discussion as to whether or not is is appropriate to even do this. I don't have enough reputation to post my answer there but this is better than any of the solutions in that link. Perhaps someone with more reputation will run across this and post a solution on that other question that links back to this one.