BaseAdapter 的 RelativeLayout addRule 不能很好地工作

Posted

技术标签:

【中文标题】BaseAdapter 的 RelativeLayout addRule 不能很好地工作【英文标题】:RelativeLayout addRule at BaseAdapter doesn't work very well 【发布时间】:2020-08-09 11:56:47 【问题描述】:

将规则之一添加到 RelativeLayout 后,我​​得到一个不太正确的结果。 ID 不适用于元素/应用不正确。这会影响必须绑定到小部件的规则。

作为一个容器,我使用 ListView 并通过 BaseAdapter 向其中添加对象。这显然不会给出预期的结果,但是在重用返回给适配器并重用的相同小部件后(保证元素不会再次更改),规则开始正常工作。

@Override
protected void onCreate(Bundle state) 
    super.onCreate(state);
    ListView view = new ListView(this);
    view.setBackgroundColor(Color.BLACK);
    view.setId("files_list".hashCode());
    view.setAdapter(new TestAdapter(this));
...
private class TestAdapter extends BaseAdapter 
...
    @Override
    public View getView(int position, View convertView, View parent) 
        if(convertView == null) convertView = inflateView();
        // only changes text & pictures, doesn't affecting display
        manipulateItem(position, convertView);
        return convertView;
...
private View inflateView() 
    RelativeLayout layout = new RelativeLayout(context);
    layout.setLayoutParams(new ViewGroup.LayoutParams(-1, -2));

    ImageView icon = new ImageView(context);
    icon.setBackgroundColor(Color.BLACK);
    icon.setPadding(20, 20, 20, 20);
    icon.setId("file_icon".hashCode());

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(110, -1);
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    params.rightMargin = 30;
    layout.addView(icon, params);

    ...

    LinearLayout additional = new LinearLayout(context);
    additional.setOrientation(LinearLayout.VERTICAL);
    additional.setGravity(Gravity.RIGHT);
    additional.setBackgroundColor(Color.RED);
    additional.setPadding(30, 0, 30, 0);
    additional.setId(java.lang.String("additional_info").hashCode());

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, -2);
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    params.addRule(RelativeLayout.CENTER_IN_PARENT);
    layout.addView(additional, params);

    ...

    LinearLayout uniqal = new LinearLayout(context);
    uniqal.setOrientation(LinearLayout.VERTICAL);
    uniqal.setBackgroundColor(Color.BLUE);
    uniqal.setId("uniqal_info".hashCode());

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, -2);
    // problem occurs here
    params.addRule(RelativeLayout.LEFT_OF, additional.getId());
    params.addRule(RelativeLayout.RIGHT_OF, icon.getId());
    params.addRule(RelativeLayout.CENTER_IN_PARENT);
    layout.addView(uniqal, params);

    ...

    return layout;

这是第一次滚动后小部件的外观:elements after first drawing screen

因此,在滚动和重复使用相同的小部件之后:working screen

在前 5 次使用后(我的测试屏幕上有这么多),一切都变得很好。第一次,视图不希望以任何方式通过 ID 附加到另一个小部件。有没有办法解决这个问题?

从应用程序 .xml 扩展布局的选项不适合我

【问题讨论】:

【参考方案1】:

手动更新布局对我有帮助,但这并不能立即奏效,我的问题仍然相关。这里是修改过的inflateView代码:

private View inflateView() 
    ...

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-2, -2);
    params.addRule(RelativeLayout.LEFT_OF, additional.getId());
    params.addRule(RelativeLayout.RIGHT_OF, icon.getId());
    params.addRule(RelativeLayout.CENTER_IN_PARENT);
    uniqal.post(new Runnable() 
        public void run() 
            uniqal.requestLayout();
        
    );
    layout.addView(uniqal, params);

    ...

    return layout;

【讨论】:

以上是关于BaseAdapter 的 RelativeLayout addRule 不能很好地工作的主要内容,如果未能解决你的问题,请参考以下文章

孟老板 BaseAdapter封装 简单封装

Android BaseAdapter用法

孟老板 BaseAdapter封装 空数据占位图

带有 BaseAdapter 的 ListView

带有 BaseAdapter 的 Android ListView 内的 ImageButton

Fragment和BaseAdapter之间的Android通信