2015-09-22 31 views
5

對於我在平板電腦上的列表視圖,我試圖讓選定的列表項選擇在選定時保持其狀態,但不幸的是我看到了一些奇怪的行爲。出於某種原因,每當我滾動列表到所選項目不可見的位置,然後滾動到所選項目可見的點時,背景顏色會意外得到重用。我相信getView方法需要做些什麼,但我不確定該如何處理這種方法。必須做些什麼才能防止背景顏色被重複使用?在平板電腦上列表滾動後意外重複使用的選定列表項背景顏色

適配器類

public class VictoriaListAdapter extends BaseAdapter { 

    private List<Victoria> mData; 
    private LayoutInflater mInflater; 

    public VictoriaListAdapter (List<Victoria> data, Context context) { 
     mData = data; 
     mData = new ArrayList(mData); 
     mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public int getCount() { 
     return mData.size(); 
    } 

    @Override 
    public String getItem(int position) { 
     return mData.get(position).getStation(); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     ViewHolder holder; 

     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.list_item_dualline, parent, false); 
      holder = new ViewHolder(); 

      holder.title = (TextView) convertView.findViewById(R.id.item_station); 
      holder.description = (TextView) convertView.findViewById(R.id.item_zone); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.title.setText(mData.get(position).getStation()); 
     holder.description.setText(mData.get(position).getZone()); 

     return convertView; 
    } 

    /** 
    * View holder 
    */ 
    static class ViewHolder { 
     private TextView title; 
     private TextView description; 
    } 
} 

片段類

public class FragmentVictoriaLine extends ListFragment { 

    private VictoriaListAdapter mAdapter; 

    public FragmentVictoriaLine() { 
    } 

    /** 
    * Whether or not the activity is in two-pane mode, i.e. running on a tablet 
    * device. 
    */ 
    public boolean mTwoPane; 

    public static FragmentVictoriaLine newInstance() { 
     return new FragmentVictoriaLine(); 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_victoria_line, container, false); 
     initialize(); 
     return view; 
    } 

    List<Victoria> list = new ArrayList<>(); 
    private void initialize() { 
     String[] items = getActivity().getResources().getStringArray(R.array.victoria_stations); 
     String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.victoria_zones); 
     for (int n = 0; n < items.length; n++){ 
      Victoria victoria = new Victoria(); 
      victoria.setID(); 
      victoria.setStation(items[n]); 
      victoria.setZone(itemDescriptions[n]); 
      list.add(victoria); 
     } 

     mAdapter = new VictoriaListAdapter(list, getActivity()); 
     setListAdapter(mAdapter); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     View v = getView(); 

     mTwoPane = getActivity().findViewById(R.id.detail_container) != null; 

     assert v != null; 
     ListView lv = (ListView)v.findViewById(android.R.id.list); 
     lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      private Victoria selectedMain; 
      private View selectedView; 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       VictoriaListAdapter adapter = (VictoriaListAdapter) parent.getAdapter(); 
       String station = adapter.getItem(position); 

       if (mTwoPane) { 
        setItemNormal(); 
        View rowView = view; 
        setItemSelected(rowView); 

        Fragment newFragment; 
        if (station.equals(view.getResources().getString(R.string.bho))) { 
         newFragment = new FragmentVictoriaBHO(); 
        } else if (station.equals(view.getResources().getString(R.string.brx))) { 
         newFragment = new FragmentVictoriaBRX(); 
        } else if (station.equals(view.getResources().getString(R.string.eus))) { 
         newFragment = new FragmentVictoriaEUS(); 
        } else if (station.equals(view.getResources().getString(R.string.fpk))) { 
         newFragment = new FragmentVictoriaFPK(); 
        } else if (station.equals(view.getResources().getString(R.string.green_park))) { 
         newFragment = new FragmentVictoriaGreenPark(); 
        } else if (station.equals(view.getResources().getString(R.string.hhy))) { 
         newFragment = new FragmentVictoriaHHY(); 
        } else if (station.equals(view.getResources().getString(R.string.kxsp))) { 
         newFragment = new FragmentVictoriaKXSP(); 
        } else { 
         newFragment = new FragmentVictoriaBHO(); 
        } 
        VictoriaLineActivity activity = (VictoriaLineActivity) view.getContext(); 
        FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction(); 
        transaction.setCustomAnimations(R.anim.fade_out, R.anim.fade_in); 
        transaction.replace(R.id.detail_container, newFragment); 
        transaction.commit(); 
       } else { 
        Intent intent; 
        if (station.equals(view.getResources().getString(R.string.bho))) { 
         intent = new Intent(getActivity(), VictoriaBHOActivity.class); 
        } else if (station.equals(view.getResources().getString(R.string.brx))) { 
         intent = new Intent(getActivity(), VictoriaBRXActivity.class); 
        } else if (station.equals(view.getResources().getString(R.string.eus))) { 
         intent = new Intent(getActivity(), VictoriaEUSActivity.class); 
        } else if (station.equals(view.getResources().getString(R.string.fpk))) { 
         intent = new Intent(getActivity(), VictoriaFPKActivity.class); 
        } else if (station.equals(view.getResources().getString(R.string.green_park))) { 
         intent = new Intent(getActivity(), VictoriaGreenParkActivity.class); 
        } else if (station.equals(view.getResources().getString(R.string.hhy))) { 
         intent = new Intent(getActivity(), VictoriaHHYActivity.class); 
        } else if (station.equals(view.getResources().getString(R.string.kxsp))) { 
         intent = new Intent(getActivity(), VictoriaKXSPActivity.class); 
        } else { 
         intent = new Intent(getActivity(), VictoriaBHOActivity.class); 
        } 
        startActivity(intent); 
       } 
      } 

      public void setItemSelected(View view) { 
       View rowView = view; 
       view.setBackgroundColor(Color.parseColor("#868F98")); 

       TextView tv0 = (TextView) rowView.findViewById(R.id.item_station); 
       tv0.setTextColor(Color.WHITE); 

       TextView tv1 = (TextView) rowView.findViewById(R.id.item_zone); 
       tv1.setTextColor(Color.WHITE); 
      } 

      public void setItemNormal() { 
       for (int i = 0; i < getListView().getChildCount(); i++) { 
        View v = getListView().getChildAt(i); 
        v.setBackgroundColor(Color.TRANSPARENT); 

        TextView tv0 = ((TextView) v.findViewById(R.id.item_station)); 
        tv0.setTextColor(Color.WHITE); 

        TextView tv1 = ((TextView) v.findViewById(R.id.item_zone)); 
        tv1.setTextColor(Color.parseColor("#B5B5B5")); 
       } 
      } 
     }); 

     super.onActivityCreated(savedInstanceState); 
    } 
} 

數據類

public class Victoria { 
    public Victoria(){} 

    private String station; 
    private String zone; 
    private boolean selected; 

    public String getStation(){ 
     return station; 
    } 

    public void setStation(String item){ 
     this.station = item; 
    } 

    public String getZone(){ 
     return zone; 
    } 

    public void setZone(String zone){ 
     this.zone = zone; 
    } 

    private int _id; 
    public void getID(int _id){ 
     this._id = _id; 
    } 

    public int setID(){ 
     return _id; 
    } 

    public boolean isSelected() { 
     return selected; 
    } 

    public void setSelected(boolean selected) { 
     this.selected = selected; 
    } 
} 
+2

這很簡單,因爲您使用的是ViewHolder模式,ViewHolder模式是設計人員重新使用現有的行結構而不創建新的模式。你必須自己明確設置所選行的顏色。 –

回答

4

滾動時通過列表中,ListView中的項目/視圖將被重用以優化內存。因此,當您將選定狀態設置爲列表項目時,您將在滾動瀏覽時在多個列表項中看到該選定狀態。防止這種情況的最好方法是保留數據模型中的狀態並設置AdaptergetView函數的狀態。

這裏是你可以做什麼 -

@Override 
public void onItemClick(AdapterView<?> parent, View view, int position,long id) { 
    VictoriaListAdapter adapter = (VictoriaListAdapter) parent.getAdapter(); 

    //reverse the selected state in data model 
    for (int i = 0; i < adapter.getCount(); i++) { 
    Victoria victoria = (Victoria)adapter.getItem(i); 
    victoria.setSelected(i == position ? true : false); 
    } 
    Victoria victoria = (Victoria)adapter.getItem(position); 

    --- 
    --- 
適配器

而且 -

@Override 
public Object getItem(int position) { 
    //Return full object, coz we need to access other 
    //member variables too 
    return mData.get(position); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ViewHolder holder; 

    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.list_item_dualline, parent, false); 
     holder = new ViewHolder(); 

     holder.title = (TextView) convertView.findViewById(R.id.item_station); 
     holder.description = (TextView) convertView.findViewById(R.id.item_zone); 

     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    Victoria victoria = (Victoria)getItem(position); 
    holder.title.setText(victoria.getStation()); 
    holder.description.setText(victoria.getZone()); 
    if (victoria.isSelected()) { 
     setItemSelected(convertView); 
    } else { 
     setItemNormal(convertView); 
    } 

    return convertView; 
} 

public void setItemSelected(View view) { 
    View rowView = view; 
    view.setBackgroundColor(Color.parseColor("#868F98")); 

    TextView tv0 = (TextView) rowView.findViewById(R.id.item_station); 
    tv0.setTextColor(Color.WHITE); 

    TextView tv1 = (TextView) rowView.findViewById(R.id.item_zone); 
    tv1.setTextColor(Color.WHITE); 
} 

public void setItemNormal(View v) { 

    v.setBackgroundColor(Color.TRANSPARENT); 

    TextView tv0 = ((TextView) v.findViewById(R.id.item_station)); 
    tv0.setTextColor(Color.WHITE); 

    TextView tv1 = ((TextView) v.findViewById(R.id.item_zone)); 
    tv1.setTextColor(Color.parseColor("#B5B5B5")); 

} 

希望它能幫助!

+0

在片段類「Victoria victoria = adapter.getItem(position);'獲取紅色下劃線,並返回此錯誤:'必需:com.packagename.data.Victoria Found:java.lang.Object'。在'Victoria victoria = adapter.getItem(position);'中的適配器'adapter'中獲得紅色下劃線,並返回此錯誤:'無法解析符號'adapter''。 [截圖1](http://picpaste.com/w54VUMiV.png)[截圖2](http://picpaste.com/zGbiKJov.png) – MacaronLover

+0

您的解決方案無法正常工作,因爲所選狀態仍在被重用。 [截圖1(第一次選擇一個項目後)](http://picpaste.com/5QdtaaDB.png); [截圖2(向下滾動列表並返回後)](http://picpaste.com/kGfwkRYr.png) – MacaronLover

+0

編輯答案。 ('onItemClick'函數) –

相關問題