在 ListActivity 的 CustomView 中以编程方式更改 LayoutParams 对某些项目没有影响

发布于 2024-12-25 18:18:40 字数 5845 浏览 2 评论 0原文

我在列表视图中呈现项目时出现奇怪的行为。我将尽力解释:

我创建了一个 CustomView 用作 ListView 中的项目。 此 CustomView 有一个 Framelayout 作为根视图和 2 个子视图:

1) 一个 LinearLayout,其中有一堆 TextView 作为子视图

2) 顶部(最后一个添加到框架布局)有一个带背景的 View 当我按下它时改变颜色的选择器。 (只是为了给用户一个视觉提示,表明我选择了该项目...

现在的问题...由于文本视图可以更改其高度,因为它们是多行的,所以我需要相应地更改顶视图的高度。 .. 由于顶视图和 LinearLayout 在 Framelayout 中位于同一级别,因此我无法在 xml 文件中执行此操作。

所以我扩展了一个 FrameLayout,膨胀了自定义视图的 xml 文件并覆盖了 onLayout(...)。这样做我可以获得 LinearLayout 的高度并将其传递到顶视图:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b){
    super.onLayout(changed, l, t, r, b);

    LinearLayout ll = (LinearLayout) findViewById(R.id.linear_layout_items);
    int height = ll.getMeasuredHeight();

    //Setting the height in the View...
    View view = findViewById(R.id.click_view);
    view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
}

现在,除了某些情况之外,这可以完美地工作......

如果屏幕能够渲染前 4 个项目,并且我滚动到第 5 个项目,则顶视图的高度(带有 id R.id.click_view)被设置为 0,尽管它设置正确......并且如果我开始滚动,这开始随机发生......

我已经在运行 android 3.1 的平板电脑上进行了测试运行 ICS 的模拟器,它工作得很好...它只在运行版本 <=2.x 的设备中失败...

有关如何修复此行为的任何提示吗?

预先感谢您的任何帮助或提示。

这是完整的代码: 活动项目

public class DemoCursorActivity extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    init();
}

private void init()
{
    MatrixCursor cursor = new MatrixCursor(new String[]{ "_id", "txt1", "txt2", "txt3","txt4" }); 
    cursor.addRow(new Object[]{ 1, "1111111111","1111111111","1111111111","1111111111" }); 
    cursor.addRow(new Object[]{ 2, "2222222222","2222222222","2222222222","2222222222" }); 
    cursor.addRow(new Object[]{ 3, "3333333333","3333333333","3333333333","3333333333" }); 
    cursor.addRow(new Object[]{ 4, "4444444444","4444444444","4444444444","4444444444" }); 
    cursor.addRow(new Object[]{ 5, "5555555555","5555555555","5555555555","5555555555" }); 
    cursor.addRow(new Object[]{ 6, "6666666666","6666666666","6666666666","6666666666" }); 
    cursor.addRow(new Object[]{ 7, "7777777777","7777777777","7777777777","7777777777" }); 
    cursor.addRow(new Object[]{ 8, "8888888888","8888888888","8888888888","8888888888" }); 


    ItemsCursorAdapter cursorAdapter = new ItemsCursorAdapter (this, cursor);

    setListAdapter(cursorAdapter); 
}

class ItemsCursorAdapter extends CursorAdapter
{
    private final LayoutInflater mInflater;

    public ItemsCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View v, Context context, Cursor cursor)
    {
        Resources res = context.getResources();

        TextView tv1 = (TextView) v.findViewById(R.id.text1);
        TextView tv2 = (TextView) v.findViewById(R.id.text2);
        TextView tv3 = (TextView) v.findViewById(R.id.text3);
        TextView tv4 = (TextView) v.findViewById(R.id.text4);

        tv1.setText(cursor.getString(1));
        tv2.setText(cursor.getString(2));
        tv3.setText(cursor.getString(3));
        tv4.setText(cursor.getString(4));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent)
    {
        View v = new ListItemWidget(context);
        bindView(v, context, cursor);
        return v;
    }
}

布局文件:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFF" >

<LinearLayout
    android:id="@+id/linear_layout_items"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/text3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/text4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />
</LinearLayout>

  <View
      android:id="@+id/click_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@drawable/group_item_backgroud_selector" />

</FrameLayout>

和我的自定义视图:

public class ListItemWidget extends FrameLayout
{
    public ListItemWidget(Context context) {
    super(context);
    inflate(context, R.layout.list_item, this);
}

    @Override
    protected void onDraw(Canvas canvas)
    {
    super.onDraw(canvas);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
    super.onLayout(changed, l, t, r, b);
    LinearLayout ll = (LinearLayout) findViewById(R.id.LinearLayout01);
    int height = ll.getMeasuredHeight();

    View view = findViewById(R.id.click_view);
    view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
    }
}

I’m having a strange behavior rendering items in a Listview. I’ll try to explain as best as I can:

I've created a CustomView to be used as items in a ListView.
This CustomView has a Framelayout as the root view and 2 child's:

1) A LinearLayout with a bunch of TextView's as childs

2) and on the top (the last to be added to the framelayout) a View with a background
selector that change color when I press it. (Just to give a visual hint to the user that I had selected the item...

Now the problem... since the textviews can change theirs heights, because they are multiline, I need to change the height of the top view accordingly...
And since the top view and the linearLayout are on the same level in the Framelayout, I cannot do this in xml file.

So I had extended an FrameLayout, inflated the xml file of the custom view and override the onLayout(...). Doing this I can get the height of the LinearLayout and pass it to the top view:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b){
    super.onLayout(changed, l, t, r, b);

    LinearLayout ll = (LinearLayout) findViewById(R.id.linear_layout_items);
    int height = ll.getMeasuredHeight();

    //Setting the height in the View...
    View view = findViewById(R.id.click_view);
    view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
}

Now this works flawlessly, except for some cases...

If the screen is capable of rendering the first 4 items and I scroll to the 5th item, the height of the top view (with the id R.id.click_view) in the is set to 0, although it was set correctly... And if I start to scroll around, this starts to happen randomly....

I've tested this in a tablet running android 3.1 and in an emulator running ICS and it works perfectly... It only fails in devices running versions <=2.x…

Any tip on how to fix this behaviour?

Thanks in advance for any help or tips.

This is the complete code:
Activity

public class DemoCursorActivity extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    init();
}

private void init()
{
    MatrixCursor cursor = new MatrixCursor(new String[]{ "_id", "txt1", "txt2", "txt3","txt4" }); 
    cursor.addRow(new Object[]{ 1, "1111111111","1111111111","1111111111","1111111111" }); 
    cursor.addRow(new Object[]{ 2, "2222222222","2222222222","2222222222","2222222222" }); 
    cursor.addRow(new Object[]{ 3, "3333333333","3333333333","3333333333","3333333333" }); 
    cursor.addRow(new Object[]{ 4, "4444444444","4444444444","4444444444","4444444444" }); 
    cursor.addRow(new Object[]{ 5, "5555555555","5555555555","5555555555","5555555555" }); 
    cursor.addRow(new Object[]{ 6, "6666666666","6666666666","6666666666","6666666666" }); 
    cursor.addRow(new Object[]{ 7, "7777777777","7777777777","7777777777","7777777777" }); 
    cursor.addRow(new Object[]{ 8, "8888888888","8888888888","8888888888","8888888888" }); 


    ItemsCursorAdapter cursorAdapter = new ItemsCursorAdapter (this, cursor);

    setListAdapter(cursorAdapter); 
}

class ItemsCursorAdapter extends CursorAdapter
{
    private final LayoutInflater mInflater;

    public ItemsCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View v, Context context, Cursor cursor)
    {
        Resources res = context.getResources();

        TextView tv1 = (TextView) v.findViewById(R.id.text1);
        TextView tv2 = (TextView) v.findViewById(R.id.text2);
        TextView tv3 = (TextView) v.findViewById(R.id.text3);
        TextView tv4 = (TextView) v.findViewById(R.id.text4);

        tv1.setText(cursor.getString(1));
        tv2.setText(cursor.getString(2));
        tv3.setText(cursor.getString(3));
        tv4.setText(cursor.getString(4));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent)
    {
        View v = new ListItemWidget(context);
        bindView(v, context, cursor);
        return v;
    }
}

The item layout file:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFF" >

<LinearLayout
    android:id="@+id/linear_layout_items"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/text3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/text4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:textColor="#000"
        android:textSize="20sp" />
</LinearLayout>

  <View
      android:id="@+id/click_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@drawable/group_item_backgroud_selector" />

</FrameLayout>

and my custom view:

public class ListItemWidget extends FrameLayout
{
    public ListItemWidget(Context context) {
    super(context);
    inflate(context, R.layout.list_item, this);
}

    @Override
    protected void onDraw(Canvas canvas)
    {
    super.onDraw(canvas);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
    super.onLayout(changed, l, t, r, b);
    LinearLayout ll = (LinearLayout) findViewById(R.id.LinearLayout01);
    int height = ll.getMeasuredHeight();

    View view = findViewById(R.id.click_view);
    view.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文