0

在 TabActivity 中,一个 TabSpec 由几个 TextView 和下面的 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>

TabSpec 与 ListView (venueviewreviews.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="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);
                }
            });

        }

    }
}

}

知道我必须解决什么问题才能在 TabSpec 中而不是在单独打开的窗口/活动中显示评论 ListView 吗?

4

3 回答 3

0

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

也许您对设置适配器的要求应该是:

lvComments.setAdapter(laComments);

或者更改为 ListActivity 而不是 Activity。

于 2012-06-02T13:31:49.003 回答
0

在 Activity 中调用 ListActivity 正在为您创建新窗口。为了避免直接在 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);
            }
        });

    }

  }
 }
于 2012-06-05T06:09:38.523 回答
0

我想我找到了解决方案:TabHost/TabSpec 以某种方式处理视图的方式非常不同,因此在 TabHost 中填充除 ListView 之外的 TextView 或其他元素会弄乱上下文堆栈。

所以我所做的是在重写的 onContentChanged() 方法中刷新引用 Buttons 和 TextViews 的变量,正如“Chris”在这里解释的那样:

@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);
}
于 2012-06-06T03:16:20.463 回答