1

從我可以收集它似乎可能是因爲我的ListView沒有顯示,我已驗證getCount返回的值不是零,但我可以看不出我做錯了什麼。ListFragment沒有渲染和getView()在適配器沒有被調用

所有的加載和行爲都像在工作,但是ListView從不出現,我在mixed.xml中的片段引用上放置了一個背景顏色,它在那裏並佔據了全屏幕,但是當我在我的背景上設置了背景顏色ListView沒有出現,就像它根本沒有被渲染。

更奇怪的是,我的適配器中沒有調用getView,這是我移植到碎片的常規活動的所有工作代碼。

我已經打過電話notifyDataSetChanged這並沒有改變任何東西,調試顯示適配器充滿數據和getCount將確實返回準確計數大於0

感謝您的幫助,我被困。

項目已經開放,可以在這裏查看http://code.google.com/p/shack-droid/source/browse/#svn%2FTrunk,但我在這裏也包括了相關的代碼。

這是ListFragment:

public class FragmentTopicView extends ListFragment implements ShackGestureEvent { 

     private ArrayList<ShackPost> posts; 
     private String storyID = null; 

     private String errorText = ""; 
     private Integer currentPage = 1; 
     private Integer storyPages = 1; 
     private String loadStoryID = null; 
     private Boolean threadLoaded = true; 
     private Hashtable<String, String> postCounts = null; 
     private AdapterLimerifficTopic tva; 

     public FragmentTopicView() { 

     } 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
       // TODO Auto-generated method stub 
       super.onCreate(savedInstanceState); 

       this.setRetainInstance(true); 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

       return inflater.inflate(R.layout.topics, null); 
     } 

     @Override 
     public void onActivityCreated(Bundle savedInstanceState) { 
       super.onActivityCreated(savedInstanceState); 

       final ShackGestureListener listener = Helper.setGestureEnabledContentView(R.layout.topics, getActivity()); 
       if (listener != null) { 
         listener.addListener(this); 
       } 

       if (savedInstanceState == null) { 
         // get the list of topics 
         GetChattyAsyncTask chatty = new GetChattyAsyncTask(getActivity()); 
         chatty.execute(); 
       } 

       ListView lv = getListView(); 
       lv.setOnScrollListener(new OnScrollListener() { 

         @Override 
         public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 

           // start loading the next page 
           if (threadLoaded && firstVisibleItem + visibleItemCount >= totalItemCount && currentPage + 1 <= storyPages) { 

             // get the list of topics 
             currentPage++; 
             GetChattyAsyncTask chatty = new GetChattyAsyncTask(getActivity()); 
             chatty.execute(); 

           } 
         } 

         @Override 
         public void onScrollStateChanged(AbsListView view, int scrollState) { 

         } 

       }); 



     } 



    class GetChattyAsyncTask extends AsyncTask<String, Void, Void> { 
       protected ProgressDialog dialog; 
       protected Context c; 

       public GetChattyAsyncTask(Context context) { 
         this.c = context; 
       } 

       @Override 
       protected Void doInBackground(String... params) { 

         threadLoaded = false; 

         try { 
           final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); 
           final String feedURL = prefs.getString("shackFeedURL", getString(R.string.default_api)); 
           final URL url; 

           if (loadStoryID != null) { 
             if (currentPage > 1) 
               url = new URL(feedURL + "/" + loadStoryID + "." + currentPage.toString() + ".xml"); 
             else 
               url = new URL(feedURL + "/" + loadStoryID + ".xml"); 
           } 
           else { 
             if (currentPage > 1) 
               url = new URL(feedURL + "/" + storyID + "." + currentPage.toString() + ".xml"); 
             else 
               url = new URL(feedURL + "/index.xml"); 
           } 

           // Get a SAXParser from the SAXPArserFactory. 
           final SAXParserFactory spf = SAXParserFactory.newInstance(); 
           final SAXParser sp = spf.newSAXParser(); 

           // Get the XMLReader of the SAXParser we created. 
           final XMLReader xr = sp.getXMLReader(); 
           // Create a new ContentHandler and apply it to the XML-Reader 
           SaxHandlerTopicView saxHandler = new SaxHandlerTopicView(c, "topic"); 

           xr.setContentHandler(saxHandler); 

           // Parse the xml-data from our URL. 
           xr.parse(new InputSource(HttpHelper.HttpRequestWithGzip(url.toString(), c))); 

           // Our ExampleHandler now provides the parsed data to us. 
           if (posts == null) { 
             posts = saxHandler.GetParsedPosts(); 
           } 
           else { 
             ArrayList<ShackPost> newPosts = saxHandler.GetParsedPosts(); 
             newPosts.removeAll(posts); 
             posts.addAll(posts.size(), newPosts); 

           } 

           storyID = saxHandler.getStoryID(); 

           storyPages = saxHandler.getStoryPageCount(); 

           if (storyPages == 0) // XML returns a 0 for stories with only 
                       // one page 
             storyPages = 1; 

         } 
         catch (Exception ex) { 
           // TODO: implement error handling 

         } 

         return null; 
       } 

       @Override 
       protected void onPreExecute() { 
         super.onPreExecute(); 

         if (currentPage == 1) 
           dialog = ProgressDialog.show(getActivity(), null, "Loading Chatty", true, true); 
         else 
           SetLoaderVisibility(View.VISIBLE); 
       } 

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

         ShowData(); 

         SetLoaderVisibility(View.GONE); 

         try { 
           dialog.dismiss(); 
         } 
         catch (Exception e) { 
         } 

       } 

     } 



    private void ShowData() { 

       if (posts != null) { 
         Hashtable<String, String> tempHash = null; 

         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
         final String login = prefs.getString("shackLogin", ""); 
         final int fontSize = Integer.parseInt(prefs.getString("fontSize", "12")); 

         try { 
           postCounts = GetPostCache(); 
         } 
         catch (Exception ex) { 

         } 
         if (postCounts != null) 
           tempHash = new Hashtable<String, String>(postCounts); 

         if (tva == null) { 
           tva = new AdapterLimerifficTopic(getActivity(), R.layout.lime_topic_row, posts, login, fontSize, tempHash); 
           setListAdapter(tva); 
         } 
         else { 
           tva.SetPosts(posts); 
           tva.notifyDataSetChanged(); 
         } 

         final ListView lv = getListView(); 
         lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { 
           @Override 
           public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { 
             menu.setHeaderTitle("Options"); 
             menu.add(0, 1, 0, "Copy Post Url to Clipboard"); 
             menu.add(0, 2, 0, "Watch Thread"); 
             menu.add(0, 3, 0, "Thread Expires In?"); 
             menu.add(0, 4, 0, "Shacker's Chatty Profile"); 
           } 
         }); 

         // update the reply counts for the listing of topics 
         try { 
           UpdatePostCache(); 

         } 
         catch (Exception e) { 

         } 

       } 
       else { 
         if (errorText.length() > 0) { 

           try { 
             new AlertDialog.Builder(getActivity()).setTitle("Error").setPositiveButton("OK", null).setMessage(errorText).show(); 
           } 
           catch (Exception ex) { 
             // could not create a alert for the error for one reason 
             // or another 
             Log.e("ShackDroid", "Unable to create error alert ActivityTopicView:468"); 
           } 
         } 
       } 
       threadLoaded = true; 
     } 

} 

這裏是我的FragmentActivity:

public class FragmentActivityTopic extends FragmentActivity { 
     @Override 
     protected void onCreate(Bundle arg) { 
       // TODO Auto-generated method stub 
       super.onCreate(arg); 

       setContentView(R.layout.mixed); 
     } 
} 

這是我使用的適配器,上面getView提到不會被調用:

public class AdapterLimerifficTopic extends BaseAdapter { 

     // private Context context; 
     private List<ShackPost> topicList; 
     private final int rowResouceID; 
     private final String shackLogin; 
     private final Typeface face; 
     private final int fontSize; 
     private final Hashtable<String, String> postCache; 
     private final String showAuthor; 
     private final Resources r; 
     private int totalNewPosts = 0; 

     LayoutInflater inflate;// = LayoutInflater.from(context); 

     public AdapterLimerifficTopic(Context context, int rowResouceID, List<ShackPost> topicList, String shackLogin, int fontSize, Hashtable<String, String> postCache) { 
       this.topicList = topicList; 
       this.rowResouceID = rowResouceID; 
       this.shackLogin = shackLogin; 
       this.fontSize = fontSize; 
       this.postCache = postCache; 
       this.r = context.getResources(); 

       face = Typeface.createFromAsset(context.getAssets(), "fonts/arial.ttf"); 

       final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 
       showAuthor = prefs.getString("showAuthor", "count"); 

       inflate = LayoutInflater.from(context); 
     } 
     public void SetPosts(List<ShackPost> posts) 
     { 
       topicList = posts; 
     } 
     @Override 
     public int getCount() { 
       return topicList.size(); 
     } 

     @Override 
     public Object getItem(int position) { 
       return topicList.get(position); 
     } 

     @Override 
     public long getItemId(int position) { 
       // return position; 
       final ShackPost post = topicList.get(position); 
       return Long.parseLong(post.getPostID()); 
     } 

     static class ViewHolder { 
       TextView posterName; 
       TextView datePosted; 
       TextView replyCount; 
       TextView newPosts; 
       TextView postText; 
       TextView viewCat; 
       RelativeLayout topicRow; 
       ImageView postTimer; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 

       // TextView tmp; 
       // final View v; 
       ViewHolder holder; 
       final ShackPost post = topicList.get(position); 

       if (convertView == null) { 
         convertView = inflate.inflate(rowResouceID, parent, false); 
         holder = new ViewHolder(); 
         holder.posterName = (TextView) convertView.findViewById(R.id.TextViewLimeAuthor); 
         holder.datePosted = (TextView) convertView.findViewById(R.id.TextViewLimePostDate); 
         holder.replyCount = (TextView) convertView.findViewById(R.id.TextViewLimePosts); 
         holder.newPosts = (TextView) convertView.findViewById(R.id.TextViewLimeNewPosts); 
         holder.postText = (TextView) convertView.findViewById(R.id.TextViewLimePostText); 
         holder.viewCat = (TextView) convertView.findViewById(R.id.TextViewLimeModTag); 
//      holder.topicRow = (RelativeLayout) convertView.findViewById(R.id.TopicRow); 
//      holder.postTimer = (ImageView) convertView.findViewById(R.id.ImageViewTopicTimer); 

//      holder.posterName.setTypeface(face); 
//      holder.datePosted.setTypeface(face); 
//      holder.replyCount.setTypeface(face); 
//      holder.newPosts.setTypeface(face); 
         holder.postText.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize); 
//      holder.postText.setTypeface(face); 

         convertView.setTag(holder); 
       } 
       else { 
         holder = (ViewHolder) convertView.getTag(); 
       } 

//    holder.postTimer.setImageResource(Helper.GetTimeLeftDrawable(post.getPostDate())); 
// 
       holder.posterName.setText(post.getPosterName()); 
// 
//    if (shackLogin.equalsIgnoreCase(post.getPosterName())) 
//      holder.posterName.setTextColor(Color.parseColor("#00BFF3")); 
//    else 
//      holder.posterName.setTextColor(Color.parseColor("#ffba00")); 
// 
       holder.datePosted.setText(Helper.FormatShackDateToTimePassed(post.getPostDate())); 

       holder.replyCount.setText(post.getReplyCount()); 
// 
//    if (showAuthor.equalsIgnoreCase("count") && post.getIsAuthorInThread()) 
//      holder.replyCount.setTextColor(Color.parseColor("#0099CC")); 
//    else 
//      holder.replyCount.setTextColor(Color.parseColor("#FFFFFF")); 
// clipped code 
       holder.postText.setText(preview); 


//    if (showAuthor.equalsIgnoreCase("topic") && post.getIsAuthorInThread()) { 
//      final Drawable d = r.getDrawable(R.drawable.background_gradient_blue); 
//      holder.topicRow.setBackgroundDrawable(d); 
//    } 
//    else 
//      holder.topicRow.setBackgroundDrawable(null); 


       // TODO: clean this up a little/also replicated in ShackDroidThread ick 
       final String postCat = post.getPostCategory(); 
       holder.viewCat.setVisibility(View.VISIBLE); 

       if (postCat.equals("offtopic")) { 
         holder.viewCat.setText("offtopic"); 
         holder.viewCat.setBackgroundColor(Color.parseColor("#444444")); 
       } 
       else if (postCat.equals("nws")) { 
         holder.viewCat.setText("nws"); 
         holder.viewCat.setBackgroundColor(Color.parseColor("#CC0000")); 
       } 
       else if (postCat.equals("political")) { 
         holder.viewCat.setText("political"); 
         holder.viewCat.setBackgroundColor(Color.parseColor("#FF8800")); 
       } 
       else if (postCat.equals("stupid")) { 
         holder.viewCat.setText("stupid"); 
         holder.viewCat.setBackgroundColor(Color.parseColor("#669900")); 
       } 
       else if (postCat.equals("informative")) { 
         holder.viewCat.setText("interesting"); 
         holder.viewCat.setBackgroundColor(Color.parseColor("#0099CC")); 
       } 
       else 
         holder.viewCat.setVisibility(View.GONE);     


       return convertView; 
     } 

     public int getTotalNewPosts() { 
       return totalNewPosts; 
     } 

} 

及相關XML:

mixed.xml(這是片段的佈局中,只有一個用於現在)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal" 
    android:id="@+id/LinearLayoutMixed"> 

    <fragment 
     android:id="@+id/MixedThreads" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     class="com.stonedonkey.shackdroid.FragmentTopicView" 
     > 
    </fragment> 

</LinearLayout> 

Topics.xml(這包含的ListView以及一個滑動盤和一些其他的東西。

<?xml version="1.0" encoding="utf-8"?> 
     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" > 

      <ListView 
       android:id="@android:id/list" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:layout_above="@+id/TopicLoader" 
       android:divider="#333333" 
       android:dividerHeight="1dip" 
       android:textColor="#FFFFFF" 

       /> 

      <RelativeLayout 
       android:id="@+id/TopicLoader" 
       android:layout_width="fill_parent" 
       android:layout_height="35dip" 
       android:layout_alignParentBottom="true" 
       android:gravity="center_horizontal" 
       android:visibility="gone" 
       android:layout_marginTop="5dip" > 

       <TextView 
        android:id="@+id/TextViewTopicLoaderText" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:focusable="false" 
        android:focusableInTouchMode="false" 
        android:text="Loading" 

        > 
       </TextView> 

       <ImageView 
        android:id="@+id/ImageViewTopicLoader" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_toRightOf="@+id/TextViewTopicLoaderText" 
        android:src="@drawable/ic_action_refresh" 
        android:layout_alignBottom="@+id/TextViewTopicLoaderText" 
        /> 
      </RelativeLayout> 

      <SlidingDrawer 
       android:id="@+id/SlidingDrawer01" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:layout_below="@+id/TopicLoader" 
       android:animateOnClick="true" 
       android:content="@+id/bookMarkParent" 
       android:handle="@+id/TextViewTrayHandle" 
       android:orientation="vertical" 
       android:paddingTop="200dip" 
       android:visibility="gone" > 

       <TextView 
        android:id="@+id/TextViewTrayHandle" 
        android:layout_width="fill_parent" 
        android:layout_height="35dip" 
        android:background="@drawable/darkgrey_gradient" 
        android:focusable="false" 
        android:focusableInTouchMode="false" 
        android:gravity="center_vertical" > 
       </TextView> 

       <RelativeLayout 
        android:id="@id/bookMarkParent" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" > 

        <ListView 
         android:id="@+id/ListViewWatchedThreads" 
         android:layout_width="fill_parent" 
         android:layout_height="fill_parent" 
         android:divider="#333333" 
         android:dividerHeight="1dip" 
         android:textColor="#FFFFFF" > 
        </ListView> 
       </RelativeLayout> 
      </SlidingDrawer> 

     </RelativeLayout> 

最後lime_topic_row這對於上述佈局ListView中我的自定義行佈局:

<?xml version="1.0" encoding="utf-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:background="#FF0000" > 

     <TextView 
      android:id="@+id/TextViewLimeModTag" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:background="#FF0000" 
      android:layout_alignParentLeft="true" 
      android:layout_marginLeft="10dip" 
      android:textColor="#000000" 
      android:padding="2dip" 
      android:textSize="10dip" 
      />  
     <TextView 
      android:id="@+id/TextViewLimePostText" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:minHeight="20dip" 
      android:padding="10dip" 
      android:layout_below="@+id/TextViewLimeModTag" 
      android:textColor="#FFFFFF" /> 

     <TextView 
      android:id="@+id/TextViewLimeAuthor" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/TextViewLimePostText" 
      android:paddingBottom="10dip" 
      android:paddingLeft="10dip" 
      android:textColor="#0099CC" /> 

     <TextView 
      android:id="@+id/TextViewPosted" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/TextViewLimePostText" 
      android:layout_toRightOf="@+id/TextViewLimeAuthor" 
      android:paddingBottom="10dip" 
      android:text=" posted " /> 

     <TextView 
      android:id="@+id/TextViewLimePostDate" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/TextViewLimePostText" 
      android:layout_toRightOf="@+id/TextViewPosted" 
      android:paddingBottom="10dip" 
      android:paddingRight="10dip" 
      android:textColor="#FF8800" /> 



     <TextView 
      android:id="@+id/TextViewLimePosts" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignBaseline="@+id/TextViewLimePostDate" 
      android:layout_marginRight="3dip" 
      android:layout_below="@+id/TextViewLimePostText" 
      android:layout_marginBottom="15dip" 
      android:layout_toLeftOf="@+id/TextViewLimeNewPosts" 
      android:background="#BBBBBB" 
      android:padding="3dip" 
      android:minWidth="25dip" 
      android:gravity="center" 
      android:textColor="#000000" /> 

     <TextView 
      android:id="@+id/TextViewLimeNewPosts" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignBaseline="@+id/TextViewLimePostDate" 
      android:layout_below="@+id/TextViewLimePostText" 
      android:layout_marginBottom="15dip" 
      android:layout_marginRight="10dip" 
      android:background="#669900" 
      android:padding="3dip" 
      android:minWidth="25dip" 
      android:gravity="center" 
      android:layout_alignParentRight="true" 
      android:textColor="#000000" /> 

    </RelativeLayout> 
+0

你在哪裏設置適配器到列表視圖? – 2012-07-20 03:16:09

+0

它在ShowData()方法中的ListFragment中設置,它在完成後在AsyncTask中調用。 – stonedonkey 2012-07-20 03:18:39

+0

你可以把項目的文件歸檔到某個地方嗎?我想查看代碼,但我不工作或有顛覆,我不想從存儲庫中複製文件。 – Luksprog 2012-07-20 06:46:53

回答

1

我想我找到了問題。這個問題似乎是因爲ShackGestureListener你設置在onActivityCreated方法在FragmentTopicView開始的:

final ShackGestureListener listener = Helper.setGestureEnabledContentView(R.layout.topics, getActivity()); 
if (listener != null) { 
    listener.addListener(this); 
} 

setGestureEnabledContentView()方法你檢查,看看用戶是否啓用了手勢的喜好或者如果Android版本是大於3.無論哪種方式,truefalse您設置FragmentActivityTopic再次(具有FragmentTopicView的佈局)的內容視圖。遺憾的是,再次設置內容視圖將覆蓋當前佈局,該佈局將ListView與數據(沒有問題的ListView)保持在一起。當您運行這些AsyncTasks以獲取數據時,最後您將數據設置在正確的ListView(由getListView返回)上,因爲getListView將保留對在onCreateView方法中設置的舊正確ListView的引用,沒有看到任何東西,因爲在setGestureEnabledContentView中你覆蓋了這個ListView

如果您簡單地註釋掉(或刪除)爲HelperHelperAPI4類中的活動設置內容視圖的行,此行爲很容易看出。另一種方式來看到你的ListView覆蓋,例如設置爲使用getListViewListViewTVA)適配器和使用getActivity().findViewById(android.R.id.list)(我做這個關於選擇菜單中的項目之一,所以我可以控制我更換適配器):

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    Intent intent; 
    switch (item.getItemId()) 
    { 
    case R.id.topic_menu_newpost: // Launch post form 
//this doesn't work as the getListView will return a reference to the old ListView 
ListView lv = getListView(); 
lv.setAdapter(tva); 
// this will work as you get a reference to the new ListView on top 
ListView lv = (ListView) getActivity().findViewById(android.R.id.list); 
lv.setAdapter(tva); 

我不知道該怎麼建議的解決方案,我不太明白你在做什麼,但我懷疑它需要來設置內容視圖活動再次(你應該從這工作)。