ListView在与之交互之前不会呈现所有项目

时间:2012-07-13 09:23:15

标签: android android-layout android-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);

5 个答案:

答案 0 :(得分:6)

尝试在runOnUIThread()方法中调用notifyDataSetChanged(),如下所示,它将像魅力一样工作。 :)

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

答案 1 :(得分:0)

我不知道导致问题的原因,但是如果你找不到合理的解决方案,你可以尝试这样的事情:

  • 每当您启动onTouchEvent()
  • 时,都会以编程方式触发ListView
  • 一旦启动ListView,就以编程方式向下滚动并备份。

等。

答案 2 :(得分:0)

将ListView小部件添加到layout.xml并向其添加列表内容。不要使用FrameLayout,因为它可能是问题的原因。它正在触摸后更新内容,因此它所处的布局没有像ListView小部件那样实现正确的onCreate()设置。

答案 3 :(得分:0)

在添加新项目后,您是否在适配器上调用了notifyDataSetChanged()方法?这会导致listview在更改基础数据集时刷新其视图。

如果仍然无效,请尝试notifyDataSetInvalidated(),使listview完全重绘。

答案 4 :(得分:0)

解决了!!!

问题在于适配器尝试重用相同的节项。不好!!!

每当我们点击某个部分时,将其更改为对部分项目进行通货膨胀!