简体   繁体   中英

RelativeLayout addRule at BaseAdapter doesn't work very well

After one of rule is added to RelativeLayout, I get a don't very correct result. ID does not apply to element/is applied incorrectly. This affects at rules that must be bound to widget.

As a container, I use ListView and add objects to it through BaseAdapter. This obviously does not give desired result, but after reusing same widget that is returned back to the adapter and reused (element is guaranteed not changing again), rules starting working correctly.

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

This is what widget will looks like after first scrolling: elements after first drawing screen

And so, after scrolling and reusing same widget: working screen

After firstly 5 uses (so much got into my test screen), everything becomes fine. For the first time, views don't want to be attached by ID to another widget in any way. Is there a way around this?

Options for inflating layout from application.xml don't suit me

Manual update of layout helped me, however this doesn't work right away and my question remains relevant. Here is modified inflateView code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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