2012-07-13 44 views
12

交互我使用我的ListView時有一個非常奇怪的問題。ListView不會渲染所有項目,直到與

只有我的適配器項目的一部分呈現在屏幕上的列表視圖中,但是當我與列表視圖交互(即試圖滾動它)時,所有項目都呈現正確。

這隻fenonemon只發生,如果我有比屏幕可以顯示更少的項目。看看下面的這些截圖。

前互動: enter image description here

相互作用後:活動 enter image description here

源代碼中添加項目:

適配器
String[] jRests = getResources().getStringArray(R.array.j_restaurants); 
     String[] lRests = getResources().getStringArray(R.array.l_restaurants); 

     items = new ArrayList<Object>(); 
     items.add(getString(R.string.campus_j)); 
     for(String item : jRests){ 
      String[] val = item.split(",,,"); 
      items.add(new FoodSectionListItem(new Restaurant(val[0], val[1], val[2], ""))); 
     } 
     items.add(getString(R.string.campus_l)); 
     for(String item : lRests){ 
      String[] val = item.split(",,,"); 
      items.add(new FoodSectionListItem(new Restaurant(val[0], val[1], val[2], ""))); 
     } 

     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     adapter = new BaseSectionAdapter(this, R.layout.list_item_fragment_header); 
     if(!isTabletView()){ 
      adapter.setSelectedItem(-1); 
     } 
     adapter.setItems(items); 

代碼:

public class BaseSectionAdapter extends AmazingAdapter { 

    private LayoutInflater inflater; 
    private int selectedItem = 0; 
    private List<Object> items; 
    private List<SectionItem> sections = new ArrayList<SectionItem>(10); 
    private List<Class> itemTypes = new ArrayList<Class>(); 
    private List<Integer> sectionPositions = new ArrayList<Integer>(); 
    private int listHeaderLayoutId; 
    private View headerView; 

    public static interface ISectionListItem { 
     public void setProps(View convertView, int position, int selectedItem); 
     public View getLayout(LayoutInflater inflater); 
    } 

    private class SectionItem implements Serializable { 
     private static final long serialVersionUID = -8930010937740160935L; 
     String text; 
     int position; 

     public SectionItem(String text, int position) { 
      this.text = text; 
      this.position = position; 
     } 
    } 

    public BaseSectionAdapter(Context context, int listHeaderLayoutId) { 
     this.listHeaderLayoutId = listHeaderLayoutId; 
     init(context); 
    } 

    public BaseSectionAdapter(Context context, int listHeaderLayoutId, List<Object> listItems) { 
     this.listHeaderLayoutId = listHeaderLayoutId; 
     init(context); 
     initListItems(listItems); 
    } 

    private void init(Context context) { 
     inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public void setSelectedItem(int position) { 
     selectedItem = position; 
    } 

// public List<ListItem> getItems() { 
//  return items; 
// } 

    private void initListItems(List<Object> itemList) { 
     int curSection = -1; 
     //int curPosition = 0; 
     //curSection = 0; 

     this.items = itemList; 
     itemTypes.clear(); 
     sections.clear(); 
     sectionPositions.clear(); 



     int listSize = itemList.size(); 
     for(int i = 0; i < listSize; i++){ 
      Object currentItem = items.get(i); 
      if(currentItem instanceof String){ 
       sections.add(new SectionItem((String) currentItem,i)); 
       curSection++; 
      } 
      if(!itemTypes.contains(currentItem.getClass())){ 
       itemTypes.add(currentItem.getClass()); 
      } 


      sectionPositions.add(curSection); 
     } 

     Log.d("test", "No of items = "+items.size()); 
     Log.d("test", "No of itemtypes = "+itemTypes.size()); 
     Log.d("test", "View type count = "+getViewTypeCount()); 
    } 

    public void setItems(List<Object> itemList) { 
     initListItems(itemList); 
    } 

    public int getCount() { 
     return items==null?0:items.size(); 
    } 

    @Override 
    public int getViewTypeCount(){ 
     return (itemTypes.size() == 0)?1:itemTypes.size(); 
    } 

    @Override 
    public int getItemViewType(int position){ 
     return itemTypes.indexOf(items.get(position).getClass()); 
    } 

    @Override 
    public boolean isEnabled(int position){ 
     return !(items.get(position) instanceof String || items.get(position) instanceof EmptySectionListItem); 
    } 

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

    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    protected void onNextPageRequested(int page) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    protected void bindSectionHeader(View view, int position, 
      boolean displaySectionHeader) { 
//  TextView lSectionTitle = (TextView) view 
//    .findViewById(R.id.txt_list_header); 
//  if (displaySectionHeader) { 
//   lSectionTitle.setVisibility(View.VISIBLE); 
//   lSectionTitle 
//     .setText(getSections()[getSectionForPosition(position)]); 
//  } else { 
//   lSectionTitle.setVisibility(View.GONE); 
//  } 
    } 

    @Override 
    public View getAmazingView(int position, View convertView, ViewGroup parent) { 
     Object curItemObject = items.get(position); 
     boolean isHeader = (curItemObject instanceof String); 

     if(convertView == null){ 
      if(isHeader && headerView != null){ 
       convertView = headerView; 
      }else if(isHeader){ 
       convertView = inflater.inflate(listHeaderLayoutId, null); 
       headerView = convertView; 
      }else{ 
       convertView = ((ISectionListItem) curItemObject).getLayout(inflater); 
      } 
     } 
     if(isHeader){ 
      TextView header = ((TextView)convertView.findViewById(R.id.txt_list_header)); 
      header.setText((String)curItemObject); 
     }else{ 
      ((ISectionListItem)curItemObject).setProps(convertView, position, selectedItem); 
     } 
     return convertView; 
    } 

    @Override 
    public void configurePinnedHeader(View header, int position, int alpha) { 

     TextView textView = ((TextView)header.findViewById(R.id.txt_list_header)); 
     textView.setText(getSections()[getSectionForPosition(position)]); 
    } 

    @Override 
    public int getPositionForSection(int section) { 
     if(section >= sections.size()){ 
      return 0; 
     } 

     return sections.get(section).position; 
    } 

    @Override 
    public int getSectionForPosition(int position) { 
     return sectionPositions.get(position); 
    } 

    @Override 
    public String[] getSections() { 
     String[] res = new String[sections.size()]; 
     for (int i = 0; i < res.length; i++) { 
      res[i] = sections.get(i).text; 

     } 
     return res; 
    } 
} 

代碼佈局:

LinearLayout layout = new LinearLayout(this); 
      layout.setOrientation(LinearLayout.HORIZONTAL); 

      FrameLayout listLayout = new FrameLayout(this); 
      LinearLayout.LayoutParams listParams = new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.MATCH_PARENT); 
      listParams.weight = 1; 
      listLayout.setId(LIST_FRAGMENT_VIEW_ID); 

      FrameLayout detailLayout = new FrameLayout(this); 
      LinearLayout.LayoutParams detailParams = new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.MATCH_PARENT); 
      detailParams.weight = 2; 
      detailLayout.setId(DETAIL_FRAGMENT_VIEW_ID); 

      layout.addView(listLayout, listParams); 
      layout.addView(detailLayout, detailParams); 

      if(savedInstanceState == null){ 

      FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 

      ft.add(listLayout.getId(), (Fragment) listFragment, TWO_PANEL_LIST_FRAGMENT_TAG); 
      ft.add(detailLayout.getId(), detailFragment); 
      ft.commit(); 

      } 
      setContentView(layout); 
+0

你可以添加適配器的一些代碼..? – Kamal 2012-07-13 09:29:37

+0

添加源代碼,您將項目添加到您的列表視圖的支持數據源,並創建適配器 – 2012-07-13 09:32:04

+0

也顯示您的ListView的佈局源。:) – 2012-07-13 09:35:15

回答

1

解決了!!!

問題在於適配器試圖重複使用相同的部分項目。不好!!!

每次我們擊中某個部分時,將其更改爲膨脹節項目!

+1

你能否幫我解決,我有同樣的問題,你能解釋一下你的解決方法嗎?我必須點擊屏幕才能加載listview – 2014-11-27 02:11:45

+1

一個正確的答案應該詳細說明如何解決問題,而不僅僅是提示它。特別是如果你回答你自己的問題...... – ndori 2017-03-21 08:07:16

0

我不知道是什麼原因造成的問題,但如果你沒有找到一個合理的解決方案,它可以嘗試這樣的事:

  • 觸發每次啓動ListView時,都會以編程方式提供onTouchEvent()
  • 向下滾動並在ListView啓動後以編程方式備份​​。

等。

0

添加的ListView控件到layout.xml並添加列表的內容了這一點。不要使用FrameLayout,因爲它可能是問題的原因。它在觸摸後更新內容,因此它所在的佈局不像ListView小部件那樣實現正確的onCreate()設置。

+0

你是什麼意思,它沒有實現正確的onCreate? 以編程方式創建佈局,然後我添加我的碎片。試圖改變兩個FrameLayout到LinearLayout,沒有什麼區別:/ – Richard 2012-07-17 07:19:14

+0

@Richard你在哪裏添加一個ListView?根據你的代碼,你沒有實現一個ListView。 – CommonKnowledge 2012-07-17 15:50:32

+0

'ft.add(listLayout.getId(),(Fragment)listFragment,TWO_PANEL_LIST_FRAGMENT_TAG);' 即時添加一個listfragment – Richard 2012-07-19 07:44:26

0

是否在添加新項目後調用適配器上的notifyDataSetChanged()方法?這會導致listview在底層數據集更改時刷新其視圖。

如果仍然不起作用,請嘗試notifyDataSetInvalidated(),導致listview完全重繪。

+0

試過這個。沒有效果。開始認爲listfragment可能是這裏的問題。 即時通訊加入 – Richard 2012-07-20 14:37:00

5

嘗試在runOnUIThread()方法中調用notifyDataSetChanged()方法,就像我在下面顯示的那樣,它將像魅力一樣工作。 :)

   runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         messageAdapter.notifyDataSetChanged(); 
        } 
       }); 
+0

顯然不是原來的問題的解決方案,但這解決了我的同樣的問題。從另一個線程調用notifyDataSetChanged()並不可靠。 – Ashley 2014-12-07 23:49:07

相關問題