13

ListView の使用中に非常に奇妙な問題が発生しました。

アダプタ アイテムの一部のみが画面上のリストビューにレンダリングされますが、リストビューを操作すると (つまり、スクロールしようとすると)、すべてのアイテムが適切にレンダリングされます。

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

相互作用の前に: ここに画像の説明を入力

インタラクション後: ここに画像の説明を入力

アイテムを追加するアクティビティのソース コード:

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);
4

5 に答える 5

6

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

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        messageAdapter.notifyDataSetChanged();
                    }
                });
于 2014-01-02T06:49:27.670 に答える
0

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

それでもうまくいかない場合は、listview を完全に再描画する notifyDataSetInvalidated() を試してください。

于 2012-07-20T09:52:03.453 に答える
0

ListView ウィジェットを layout.xml に追加し、それにリストのコンテンツを追加します。問題の原因である可能性があるため、FrameLayout は使用しないでください。タッチ後にコンテンツを更新しているため、それがオンになっているレイアウトは、ListView ウィジェットのように正しい onCreate() セットアップを実装していません。

于 2012-07-16T22:56:50.207 に答える
0

解決しました!!!

問題は、アダプタが同じセクション項目を再利用しようとしたことにありました。良くない!!!

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

于 2012-09-05T08:51:27.327 に答える
0

問題の原因はわかりませんが、論理的な解決策が見つからない場合は、次のようなことを試すことができます。

  • onTouchEvent()を起動するたびに、プログラムで をトリガーしますListView
  • ListView が起動されるとすぐに、プログラムによって下にスクロールしてバックアップします。

等..

于 2012-07-16T09:01:10.847 に答える