8217


AndroidのListViewに関する質問です｡

<http://www.breakingwap.com/wp-content/uploads/8924-a.sc.jpg>

上のリンクのような`NavigationDrawer`でなおかつ､この画像でいう､アイコンやメールアドレスがある部分とFooterに当たる部分を`NavigationDrawer`の上部､下部に固定したレイアウトを作りたいと思いまして､以下のようなレイアウトで書いたのですが､例えば､縦画面などで､ListViewをスクロールする必要がなく､要素がすべて表示されるときには､正しく表示されるのですが､横画面などでListViewのスクロールが必要なときにスクロールをするたびにそのListViewの順番が変わってしまいます｡

**NavigationDrawerのレイアウトの概略**

[code]

    <LinearLayout>
      <RelativeLayout>
          //View
      </RelativeLayout>
      <ListView
          android:layout_weight="1"
      </ListView>
      <LinearLayout>
          //View
      </LinearLayout>
    </LinearLayout
    
[/code]

また､以下のサイトを参考にしました｡  
<http://d.hatena.ne.jp/windbell/20120701>  
<http://d.hatena.ne.jp/nkawamura/20130818/1376815735>

回答よろしくお願いします｡

**追記(リストアダプター)**

[code]

    //ListViewのViewHolder
        private static class ViewHolder{
            TextView textView;
            ImageView imageView;
            LinearLayout itemParent;
        }
    
        //ListViewのItemデータ
        private class NavigationDrawerItem {
            public String text;
            public int icon;
    
            public NavigationDrawerItem(String text, int icon){
                this.text=text;
                this.icon=icon;
            }
        }
    
        //CustomArrayAdapter
        private class NavigationDrawerAdapter extends ArrayAdapter<NavigationDrawerItem>{
    
            private LayoutInflater inflater;
            private int resourceId;
            public NavigationDrawerAdapter(Context context, int resource, List<NavigationDrawerItem> objects) {
                super(context, resource, objects);
                this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                this.resourceId=resource;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent){
                ViewHolder holder;
    
                if(convertView==null){
                    convertView=inflater.inflate(resourceId, parent, false);
                    holder = new ViewHolder();
                    holder.textView = (TextView)convertView.findViewById(R.id.text);
                    holder.imageView = (ImageView)convertView.findViewById(R.id.icon);
                    holder.itemParent = (LinearLayout)convertView.findViewById(R.id.item_parent);
                    convertView.setTag(holder);
                }else{
                    holder = (ViewHolder)convertView.getTag();
                }
    
                if(!isEnabled(position)){
                    //区切り線を入れる
                    View border = new View(getActivity());
                    border.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
                    border.setBackgroundColor(getResources().getColor(R.color.border_color));
                    holder.itemParent.addView(border);
                }else{
                    if(mCurrentSelectedPosition==position){
                        holder.itemParent.setBackgroundResource(R.color.selected);
                    }else{
                        holder.itemParent.setBackgroundResource(android.R.color.white);
                    }
                    NavigationDrawerItem item = getItem(position);
                    holder.imageView.setImageResource(item.icon);
                    holder.textView.setText(item.text);
                }
    
                return convertView;
            }
    
    
            @Override
            public boolean isEnabled(int position){
                return !(getItem(position).text.startsWith("-"));
            }
    
        }
    
[/code]


CC BY-SA 3.0
2015-03-21T06:28:53.227
8210
2015-03-21T14:05:51.517
2015-03-21T11:14:47.707
7232
7232
question
android android-layout
ListViewの順番がスクロールするたびに変わってしまう｡


再利用された`convertView`の前の値を消していないため、行が入れ替わったように見えているのだと思います。

`Adapter`の`getView()`の`convertView`引数は、スクロールするくらい行が多い場合、見えなくなった`convertView`が新しく見えるようになった行の`getView()`のときに再利用されます。

`getView()`で修正すべき点は2点あります。

  1. 区切り線だった場合、`border`を生成していますが、再利用されたときも生成してしまいます。  
これは、アイテムの`layout xml`に`border`も含めてしまうのがよいかと思います。

  2. 区切り線だった場合、`holder.imageview`や`holder.textView`をクリアしていません。今回は区切り線のときは見えないようにするのがよいかと思います。

具体的には

[code]

    if (!isEnabled(position)) {
        holder.border.setVisibility(View.VISIBLE);
        holder.textView.setVisibility(View.GONE);
        holder.imageView.setVisibility(View.GONE);
    } else {
        holder.border.setVisibility(View.GONE);
        holder.textView.setVisibility(View.VISIBLE);
        holder.imageView.setVisibility(View.VISIBLE);
        // テキストやアイコンを設定
        ・・・省略・・・
    }
    
[/code]

こんな感じで正しく動くはずです。


CC BY-SA 3.0
2015-03-21T13:28:31.100
8217
2015-03-21T14:05:51.517
2015-03-21T14:05:51.517
8216
8216
8210
answer