在Tabspec元素中填充Listview

时间:2012-06-02 11:48:48

标签: android android-asynctask android-tabhost

在TabActivity中,一个TabSpec包含一些TextViews,下面是一个ListView元素。我想用外部数据库中的AsyncTask填充ListView。在我的应用程序的所有其他部分使用“标准”布局,这工作正常,但似乎嵌套ListView创建一个问题。 如果我将数据加载到TabSpec的ListView中 - 应用程序会在TabActivity上创建一个新的“窗口”,所以“后退”按钮会将我带回(空)TabSpec。

这是我的代码:

TabHost(venueview.xml):

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TabWidget
        android:id="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
</LinearLayout>
</TabHost>

使用ListView(venueviewreviews.xml)的TabSpec:

<?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="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/txtvname_r"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="txtvname" />
<RatingBar
    android:id="@+id/ratingBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<Button
    android:id="@+id/btnRatingSubmit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
</LinearLayout>

以下是创建TabHost的代码:

public class VViewActivity extends TabActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.venueview);

    TabHost tabHost = getTabHost();

    TabSpec vinfospec = tabHost.newTabSpec("Info");
    vinfospec.setIndicator("Info",
            getResources().getDrawable(R.drawable.ic_info));
    Intent vinfoIntent = new Intent(this, VViewBasicActivity.class);
    vinfospec.setContent(vinfoIntent);

    TabSpec vmapspec = tabHost.newTabSpec("Map");
    vmapspec.setIndicator("Location",
            getResources().getDrawable(R.drawable.ic_map));
    Intent vmapIntent = new Intent(this, VViewMapActivity.class);
    vmapspec.setContent(vmapIntent);

    TabSpec vreviewsspec = tabHost.newTabSpec("Reviews");
    vreviewsspec.setIndicator("Reviews",
            getResources().getDrawable(R.drawable.ic_review));
    Intent vreviewsIntent = new Intent(this, VViewReviewsActivity.class);
    vreviewsspec.setContent(vreviewsIntent);

    // Adding all TabSpec to the TabHost for display
    tabHost.addTab(vinfospec);
    tabHost.addTab(vmapspec);
    tabHost.addTab(vreviewsspec);

}

}

这就是我觉得必须有一些问题来源(双关语)的部分 - 设置TabSpec并使用ListView填充并正确显示的代码:

public class VViewReviewsActivity extends Activity {
private RatingBar ratingBar;
private TextView txtvname_r;
private Button btnRatingSubmit;
private ListView lvComments;
private static ListAdapter laComments;
String vid;
String vname;
String rating;

private static ArrayList<HashMap<String, String>> commentsList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.venueviewreviews);

    ListView lvComments = (ListView)findViewById(R.id.list);

    Intent lc = new Intent(this, GetVenueComments.class);
    lc.putExtra("vid",vid);
    startActivity(lc);

}


public static class GetVenueComments extends ListActivity {
    JSONParser jParser = new JSONParser();
    JSONArray comments = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.venueviewreviews);

        commentsList = new ArrayList<HashMap<String, String>>();
        new LoadAllVenues().execute();

    }

    /**
     * Background Async Task to Load all venues via HTTP Request
     * */
    class LoadAllVenues extends AsyncTask<String, String, String> {

        protected String doInBackground(String... args) {
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            Intent iCurr = getIntent();
            JSONObject json = jParser.makeHttpRequest(
                    getString(R.string.urlVenueComments), "GET", params);

            try {
                // Checking for SUCCESS TAG
                int success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    // products found

                    // Getting Array of Products
                    comments = json.getJSONArray(TAG_COMMENTS);

                    // looping through All Products
                    for (int i = 0; i < comments.length(); i++) {
                        JSONObject c = comments.getJSONObject(i);


                        // creating new HashMap
                        HashMap<String, String> hashmap = new HashMap<String, String>();

                        // adding each child node to HashMap key => value
                        hashmap.put(TAG_COMMENTS_ID, cid);
                        hashmap.put(TAG_COMMENTS_COMMENT, ctext);

                        // adding HashList to ArrayList
                        commentsList.add(hashmap);
                    }
                } else {
                    // cut to save space
                }
            } catch (JSONException e) {
                // cut to save space
            }

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
                    // Updating parsed JSON data into ListView
                    laComments = new SimpleAdapter(
                            GetVenueComments.this,
                            commentsList,
                            R.layout.commentlistitem,
                            new String[] { TAG_COMMENTS_ID,
                                                                            TAG_COMMENTS_COMMENT }, new int[] {
                                    R.id.CommentList_id,
                                                                            R.id.CommentList_comment });
                    // updating listview
                    setListAdapter(laComments);
                }
            });

        }

    }
}

}

我知道要修复哪些注释ListView会在TabSpec中显示,而不是在单独打开的窗口/活动中显示?

3 个答案:

答案 0 :(得分:0)

您的列表视图是在活动中定义的,而不是在ListActivity中定义的。设置适配器的方法不同......

也许你设置适配器的呼吁应该是:

lvComments.setAdapter(laComments);

或者更改为ListActivity而不是Activity。

答案 1 :(得分:0)

调用ListActivity Inside Activity正在为你创建一个新窗口。为了避免在TabActivity(VViewActivity)中直接注册ListActivity(GetVenueComments)..我在下面做了检查

public class VViewActivity extends TabActivity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.venueview);

TabHost tabHost = getTabHost();

TabSpec vinfospec = tabHost.newTabSpec("Info");
vinfospec.setIndicator("Info",
        getResources().getDrawable(R.drawable.ic_info));
Intent vinfoIntent = new Intent(this, VViewBasicActivity.class);
vinfospec.setContent(vinfoIntent);

TabSpec vmapspec = tabHost.newTabSpec("Map");
vmapspec.setIndicator("Location",
        getResources().getDrawable(R.drawable.ic_map));
Intent vmapIntent = new Intent(this, VViewMapActivity.class);
vmapspec.setContent(vmapIntent);

TabSpec vreviewsspec = tabHost.newTabSpec("Reviews");
vreviewsspec.setIndicator("Reviews",
        getResources().getDrawable(R.drawable.ic_review));
Intent vreviewsIntent = new Intent(this, GetVenueComments.class);
vreviewsspec.setContent(vreviewsIntent);

// Adding all TabSpec to the TabHost for display
tabHost.addTab(vinfospec);
tabHost.addTab(vmapspec);
tabHost.addTab(vreviewsspec);

 tabHost.setCurrentTab(2);

 }

}



public static class GetVenueComments extends ListActivity {
JSONParser jParser = new JSONParser();
JSONArray comments = null;

private RatingBar ratingBar;
private TextView txtvname_r;
private Button btnRatingSubmit;
private ListView lvComments;
private static ListAdapter laComments;
String vid;
String vname;
String rating;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.venueviewreviews);

    ListView lvComments = (ListView)findViewById(R.id.list);

    commentsList = new ArrayList<HashMap<String, String>>();
    new LoadAllVenues().execute();

}

/**
 * Background Async Task to Load all venues via HTTP Request
 * */
class LoadAllVenues extends AsyncTask<String, String, String> {

    protected String doInBackground(String... args) {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        Intent iCurr = getIntent();
        JSONObject json = jParser.makeHttpRequest(
                getString(R.string.urlVenueComments), "GET", params);

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                // products found

                // Getting Array of Products
                comments = json.getJSONArray(TAG_COMMENTS);

                // looping through All Products
                for (int i = 0; i < comments.length(); i++) {
                    JSONObject c = comments.getJSONObject(i);


                    // creating new HashMap
                    HashMap<String, String> hashmap = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    hashmap.put(TAG_COMMENTS_ID, cid);
                    hashmap.put(TAG_COMMENTS_COMMENT, ctext);

                    // adding HashList to ArrayList
                    commentsList.add(hashmap);
                }
            } else {
                // cut to save space
            }
        } catch (JSONException e) {
            // cut to save space
        }

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                // Updating parsed JSON data into ListView
                laComments = new SimpleAdapter(
                        GetVenueComments.this,
                        commentsList,
                        R.layout.commentlistitem,
                        new String[] { TAG_COMMENTS_ID,
                                                                        TAG_COMMENTS_COMMENT }, new int[] {
                                R.id.CommentList_id,
                                                                        R.id.CommentList_comment });
                // updating listview
                setListAdapter(laComments);
            }
        });

    }

  }
 }

答案 2 :(得分:0)

我认为我找到了解决方案:不知何故,TabHost / TabSpec以非常不同的方式处理视图,因此使用TextView或除了要在TabHost中填充的ListView之外的其他元素,会混淆上下文堆栈。

所以我所做的就是在重写的onContentChanged()方法中刷新引用Buttons和TextViews的变量,因为“Chris”解释了here

@Override
public void onContentChanged() {
    // refresh with current view, otherwise NullPointerException on
    // OnPostExecute() when trying to set value of the field with
    // setText()!!
    super.onContentChanged();

    btnRatingSubmit = (Button) VViewReviewsActivity.this
            .findViewById(R.id.btnRatingSubmit);
    txtvname_r = (TextView) VViewReviewsActivity.this
            .findViewById(R.id.txtvname_r);
    ratingBar = (RatingBar) VViewReviewsActivity.this
            .findViewById(R.id.ratingBar);
}