Pradeep Mittal
Pradeep Mittal

Reputation: 593

Adding a view dynamically not showing view

I am using following code to inflate a view in my layout under its child LinearLayout:

LayoutInflater vi = (LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);
// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
 textView.setText("your text");
// insert into main view
View insertPoint = findViewById(R.id.insert_point);
((ViewGroup) insertPoint).addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

But I can't see my view there. It shows up when I rotate my screen to landscape view. How to fix this?

EDIT:

Here is basically what I am doing. I have a TabActivity with two tabs. I use an application global which store a flag and TabHost of my TabActivity. I am also using a thread in the second tab activity which is monitoring the application global continuously to monitor flag. When I click a button in my first tab, I set the global to true. The thread in the second tab check its value. When it gets true, I run the async task and shift the current showing window to the second tab using my TabHost stired in ApplicationGlobal.

Code of second tab:

public class ShowDownloadsActivity extends Activity {
    private List<String> list;
    ApplicationGlobal ap;
    String tempUrl = "";
    LinearLayout lly;
    LayoutInflater inflater;
    Context con;
    static int k = 0;
    static int tmp = 0;
    static int size = 0;
    View insertPoint;
    View v;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.shwds);
        con = this;
        v = LayoutInflater.from(this).inflate(R.layout.downloadlistrow, null);
        insertPoint = (View) findViewById(R.id.layout_vids);
        inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ap = (ApplicationGlobal) getApplication();
        lly = (LinearLayout) findViewById(R.id.layout_vids);

        Thread thread1 = new Thread() {
            public void run() {
                try {
                    boolean flg = ap.getFlag();
                    if (flg) {
                        tempUrl = ap.getUrl();
                        ap.setUrl("");
                        flg = false;
                        new downloadVideo().execute();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        thread1.run();
    }

    class downloadVideo extends AsyncTask<Hashtable<String, String>, String, String> {
        String resp = "";

        protected void onProgressUpdate(String... values) {

        }

        @Override
        protected void onPreExecute() {
            // fill in any details dynamically here 
            TextView textView = (TextView) v.findViewById(R.id.siz);
            textView.setText("your text");
            // insert into main view 
            addContentView(v, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(Hashtable<String, String>... prmss) {
            try {
                final int return resp;
            }

            @Override
            protected void onPostExecute (String result){
                super.onPostExecute(result);
            }
        }
    }
}

Upvotes: 7

Views: 10393

Answers (5)

Janos Vinceller
Janos Vinceller

Reputation: 1266

Some years after you were asking this question :) I recognized the problem after reading your last comment: "For which view shall I call invalidate()? I need to run the addView function in an async task. Like View.invalidate(); Which view? – Pradeep Mittal Oct 26 '13 at 5:41"

Your issue is the following. You are trying to insert those views after running an asynchronous task. For that you have to be on the UI thread, you should never access the view from another thread, as the UI thread.

Try to wrap everything you do on your UI in a

runOnUiThread(new Runnable() {
    @Override
    public void run() { ... code changing the UI ... }
});

So try to change your onPreExecute like this:

@Override
protected void onPreExecute() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            // fill in any details dynamically here 
            TextView textView = (TextView) v.findViewById(R.id.siz);
            textView.setText("your text");
            // insert into main view 
            addContentView(v, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));

            // maybe this will be needed too: getView().invalidate();
        }
    });

    super.onPreExecute();
}

May you'll need that getView().invalidate() too.

I did not try this though, so please give me feedback, if it helps.

Upvotes: 0

Vahe Gharibyan
Vahe Gharibyan

Reputation: 5683

That is because parent view already measured her children. If you add view after measuring you should call

View.invalidate()

Also make sure does the child view visibility is View.visible and the view bounds is not 0;

Upvotes: 0

jc12
jc12

Reputation: 1829

Sometimes the issue is that you were expecting the LinearLayout to be vertical orientation, but if you don't set it to vertical, then the LinearLayout defaults to horizontal orientation, which if there is already an item with match parent width, then you won't see your additional items.

Upvotes: 2

Amit Gupta
Amit Gupta

Reputation: 8939

First Initialize your Layout to which you want to add subview.

For example

LinearLayout layout=(LinearLayout)findViewById(R.id.your_root_layout);

Then inflate your layout like below

LayoutInflater mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    View v= (View) mInflater.inflate(R.layout.your_layout, null);
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
layout.addView(textView, p);

Hope this will help you.

Upvotes: 3

Hareshkumar Chhelana
Hareshkumar Chhelana

Reputation: 24848

// try this
**main.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dp"
    android:orientation="vertical">
</LinearLayout>

**your_layout.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/a_text_view"/>
</LinearLayout>

**MyActivity**
public class MyActivity extends Activity  {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        View v = LayoutInflater.from(this).inflate(R.layout.your_layout, null);
        TextView textView = (TextView) v.findViewById(R.id.a_text_view);
        textView.setText("your text");
        addContentView(v, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
    }
}

Upvotes: -1

Related Questions