2012-07-13 6 views
12

ListViewの使用中に非常に奇妙な問題があります。ListViewは、対話するまですべての項目をレンダリングしません。

私のアダプタアイテムの一部だけがスクリーン上のリストビューでレンダリングされますが、リストビューとやり取りするとき(つまり、スクロールしようとするとき)、すべてのアイテムが適切にレンダリングされます。

このフェノンemonは、画面よりもアイテムが少ない場合にのみ発生します。以下のスクリーンショットをご覧ください。

前に相互作用:相互作用した後 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

+0

リストビューのバッキングデータソースにアイテムを追加するソースコードを追加し、アダプタを作成すると、ListViewのレイアウトソースも表示されます。 –

+0

:) –

答えて

1

解決済み!

アダプターが同じセクション項目を再利用しようとしたときに問題が発生しました。良くない!!!

セクションを叩くたびにセクションアイテムを膨らませるように変更しました!

+1

私は同じ問題を抱えています。解決方法を説明できますか?私はリストビューをロードするために画面をクリックする必要があります –

+1

適切な答えは、単にそれをヒントではなく、問題を解決する方法を詳述する必要があります。特にあなた自身の質問に答える場合は... – ndori

0

私は、問題の原因を知らないが、あなたがそれに論理的な解決策が見つからない場合は、このような何かを試みることができる:

  • トリガーをListViewを起動するたびにプログラムによってonTouchEvent()が表示されます。
  • ListViewを起動するとすぐにプログラムによってスクロールダウンしてバックアップを行います。

など。

0

layout.xmlとそれにリストの内容を追加してリストビューウィジェットを追加します。 FrameLayoutを使用しないでください。おそらく問題の原因です。タッチ後にコンテンツを更新しているため、レイアウトがオンの場合でも、ListViewウィジェットと同じonCreate()設定が実装されていません。

+0

正しいonCreateを実装していないのはどういう意味ですか? レイアウトをプログラムで作成してから、私のフラグメントを追加します。 2つのFrameLayoutをLinearLayoutに変更しようとしましたが、違いはありません:/ – Richard

+0

@リチャードどこListViewを追加していますか?あなたのコードによると、ListViewを実装していません。 – CommonKnowledge

+0

'ft.add(listLayout.getId()、(フラグメント)listFragment、TWO_PANEL_LIST_FRAGMENT_TAG); ' im listfragmentを追加する – Richard

0

新しい項目を追加した後、アダプタのnotifyDataSetChanged()メソッドを呼び出していますか?これにより、基になるデータセットが変更されたときにリストビューがそのビューを更新します。

まだ動作しない場合は、listviewを完全に再描画させるnotifyDataSetInvalidated()を試してください。

+0

これを試してみてください。効果はありません。リスト断片がここで問題になるかもしれないと考えることを始めます。 Imを追加する – Richard

5

私は以下のようにrunOnUIThread()メソッドでnotifyDataSetChanged()を呼び出すと、魅力的に機能します。 :)

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

明らかに元の質問の解決策ではありませんが、これは私にとって同じ問題を解決しました。他のスレッドからnotifyDataSetChanged()を呼び出すことは信頼できません。 – Ashley

関連する問題