2012-07-13 2 views
12

ListView를 사용하는 동안 매우 이상한 문제가 있습니다.ListView는 상호 작용할 때까지 모든 항목을 렌더링하지 않습니다.

내 어댑터 항목의 일부만 화면의 listview에서 렌더링되지만 목록보기 (즉, 스크롤하려고 시도)와 상호 작용할 때 모든 항목이 올바르게 렌더링됩니다.

이 fenemonemon은 화면보다 항목 수가 적은 경우에만 발생합니다. 아래의 스크린 샷을 살펴보십시오.

전에 상호 작용 : 상호 작용 후 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

목록 뷰의 백업 데이터 소스에 항목을 추가 할 소스 코드를 추가하고 어댑터를 creatting하면 –

+0

은 ListView의 레이아웃 소스도 표시합니다.:) –

답변

1

해결했습니다!

동일한 섹션 항목을 다시 사용하려고하는 어댑터에 문제가있었습니다. 안좋다!!!

섹션을 공격 할 때마다 섹션 항목을 부 풀리도록 변경했습니다.

+1

도와 주시겠습니까? 같은 문제가 있습니다. 해결 방법을 설명해 주시겠습니까? 목록보기를로드하려면 화면을 클릭해야합니다. –

+1

정답은 문제를 해결하는 방법을 자세히 알려주고 힌트가 아닙니다. 특히 자신의 질문에 대답한다면 ... – ndori

0

내가 문제의 원인을 잘 모릅니다,하지만 당신은 그것을 논리적 인 해결책을 찾을 수없는 경우에는이 같은 시도 할 수 :

  • 트리거를 ListView을 실행할 때마다 프로그래밍 방식으로 onTouchEvent()을 입력하십시오.
  • ListView가 시작되는 즉시 프로그래밍 방식으로 스크롤을 내리고 백업합니다.

0

layout.xml 그에게 목록의 내용을 추가 할 수있는 ListView 위젯을 추가합니다. 아마도 FrameLayout을 사용하지 마십시오. 문제의 원인 일 수 있습니다. 터치 후 내용을 업데이트하므로 ListView 위젯에있는 올바른 onCreate() 설정을 구현하지 않습니다.

+0

올바른 onCreate를 구현하지 않는다는 것은 무엇을 의미합니까? 레이아웃을 프로그래밍 방식으로 작성하면 조각을 추가합니다. 두 FrameLayout을 LinearLayout으로 변경하려고 시도했지만 아무런 차이가 없었습니다./ – Richard

+0

@ 리차드 ListView를 어디에서 추가하고 있습니까? 귀하의 코드에 따르면 ListView를 구현하지 않습니다. – CommonKnowledge

+0

'ft.add (listLayout.getId(), (Fragment) listFragment, TWO_PANEL_LIST_FRAGMENT_TAG); ' 메신저 목록 조각 추가 – Richard

0

새 항목을 추가 한 후 어댑터에서 notifyDataSetChanged() 메서드를 호출하고 있습니까? 이렇게하면 기본 데이터 집합이 변경 될 때 listview의 뷰가 새로 고쳐집니다.

여전히 작동하지 않으면 listview가 완전히 다시 그리도록하는 notifyDataSetInvalidated()를 시도해보십시오.

+0

시도했습니다. 효과가 없습니다. listfragment가 여기에서 문제가 될지도 모른다고 생각하기 시작합니다. Im를 추가 할 때 – Richard

5

아래에 표시된 것처럼 runOnUIThread() 메서드에서 notifyDataSetChanged()를 호출하면 매력처럼 작동합니다. :)

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

분명히 원래 질문에 대한 해결책이 아니지만, 이것은 나에게 같은 문제를 해결했습니다. 다른 스레드에서 notifyDataSetChanged()를 호출하면 신뢰할 수 없습니다. – Ashley

관련 문제