开发者

Refreshing a LinearLayout after adding a view

开发者 https://www.devze.com 2022-12-24 09:45 出处:网络
I\'m trying to ad开发者_StackOverflow中文版d views dynamically to a linearlayout. I see through getChildCount() that the views are added to the layout, but even calling invalidate() on the layout does

I'm trying to ad开发者_StackOverflow中文版d views dynamically to a linearlayout. I see through getChildCount() that the views are added to the layout, but even calling invalidate() on the layout doesn't give me the childs showed up.

Am I missing something?


A couple of things you can check in your code:

  • On the View that is being added, check that you call its setLayoutParameter method with an appropriate ViewGroup.LayoutParameter.
  • When you adding the new Views, make sure you are doing it on the UI thread. To do this, you can use the parent View's post method.

This self contained example adds a TextView after a short delay when it starts:

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ProgrammticView extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final LinearLayout layout = new LinearLayout(this);
        layout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.FILL_PARENT));

        setContentView(layout);

        // This is just going to programatically add a view after a short delay.
        Timer timing = new Timer();
        timing.schedule(new TimerTask() {

            @Override
            public void run() {
                final TextView child = new TextView(ProgrammticView.this);
                child.setText("Hello World!");
                child.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.FILL_PARENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT));

                // When adding another view, make sure you do it on the UI
                // thread.
                layout.post(new Runnable() {

                    public void run() {
                        layout.addView(child);
                    }
                });
            }
        }, 5000);
    }
}


I had the same problem and noticed that my overriden onMeasure() method wasn't called after the invalidate. So I created my own subroutine in the LinearLayout and called it before the invalidate() method.

Here is the code for an vertical LinearLayout:

private void measure() {
    if (this.getOrientation() == LinearLayout.VERTICAL) {
        int h = 0;
        int w = 0;
        this.measureChildren(0, 0);
        for (int i = 0; i < this.getChildCount(); i++) {
            View v = this.getChildAt(i);
            h += v.getMeasuredHeight();
            w = (w < v.getMeasuredWidth()) ? v.getMeasuredWidth() : w;
        }
        height = (h < height) ? height : h;
        width = (w < width) ? width : w;
    }
    this.setMeasuredDimension(width, height);
}


I spent a lot of time to solve this problem too. And I found a simple method of refresh LinearLayout in 3 lines of code

You must set transperent color in style.xml

<color name="transparent">#00000000</color>

And in the code just call to set background

LinearLayout ll = (LinearLayout) findViewById(R.id.noteList);
ll.setBackgroundColor(getResources().getColor(R.color.transparent));
ll.invalidate();

If you has drawable background call

ll.setBackgroundResource(R.drawable.your_drawable);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号