1. 程式人生 > >【Android實戰】HorizontalScrollView實現可滑動GridView

【Android實戰】HorizontalScrollView實現可滑動GridView

首先申明一下:該種方法存在問題,但是不要灰心,因為這個問題才催生了接下來的更優方案,請往下看

先說一下之前的解決方案吧

佈局檔案

 <HorizontalScrollView
        android:id="@+id/talent_label_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/start_live_btn"
        android:layout_centerHorizontal="true"
        android:layout_margin="5dp"
        android:layout_marginBottom="15dp"
        android:layout_marginLeft="12dp"
        android:layout_marginRight="12dp"
        android:scrollbarSize="0sp"
        android:scrollbarStyle="insideOverlay"
        android:overScrollMode="never"
        android:scrollbars="none">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_margin="10dp">

            <GridView
                android:id="@+id/talent_label"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:columnWidth="54dp"
                android:gravity="center"
                android:horizontalSpacing="5dp"
                android:numColumns="auto_fit"
                android:stretchMode="columnWidth"
                ></GridView>
        </LinearLayout>
    </HorizontalScrollView>
GridView設定
private GridView TLgrid;
 TLgrid = (GridView) this.findViewById(R.id.talent_label);

        TLAdapter = new TalentLabelAdapter(this);
        TLgrid.setAdapter(TLAdapter);
        TLgrid.setSelector(new ColorDrawable(Color.TRANSPARENT));// 定製當點選GridView時的背景顏色
        TLgrid.setOnItemClickListener(this);
然後獲取資料後,根據資料的大小動態計算GridView的寬度
    public void setGridView(int size){
        int length = 67;
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        float density = dm.density;
        int gridviewWidth = (int) (size * (length + 6) * density);
        int itemWidth = (int) (length * density);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                gridviewWidth, LinearLayout.LayoutParams.FILL_PARENT);
        TLgrid.setLayoutParams(params); // 設定GirdView佈局引數,橫向佈局的關鍵
        TLgrid.setColumnWidth(itemWidth); // 設定列表項寬
        //theLayout.TLgrid.setHorizontalSpacing(5); // 設定列表項水平間距
        TLgrid.setStretchMode(GridView.NO_STRETCH);
        TLgrid.setNumColumns(size); // 設定列數量=列表集合數
    }
實現介面 OnItemClickListener,完成點選事件
  @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        ArrayList<TalentLableItem> showItems = new ArrayList<TalentLableItem>();
        showItems = TLAdapter.getItems();
        int count = 0;
        for (TalentLableItem item : showItems) {
            if (item.isSelected()) {
                count++;
            }
        }
        if (count < 3) {
            TLAdapter.setSeclection(position);
            TLAdapter.notifyDataSetChanged();
        } else {
            if (items.get(position).isSelected()) {
                TLAdapter.setSeclection(position);
                TLAdapter.notifyDataSetChanged();
            } else {
                ToastUtils.toast(this, "最多隻能選擇三個標籤");
            }

        }
    }
介面卡:
public class TalentLabelAdapter extends BaseAdapter {

    private static final String TAG = "TalentLabelAdapter";
    private Context context;
    private ArrayList<TalentLableItem> items;
    private LayoutInflater mInflater;
    
    private int clickTemp = -1;

    public TalentLabelAdapter(Context context) {
        super();
        this.context = context;
        items = new ArrayList<TalentLableItem>();
        mInflater = LayoutInflater.from(context);
    }

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

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.e(TAG,position+"AAAAAA");
        ViewHolder holder = null;
        TalentLableItem TLItem = items.get(position);
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.talent_label_item, null);
            holder = new ViewHolder();
          
            holder.label = (TextView) convertView.findViewById(R.id.label);
            
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
       

        holder.label.setText("#"+TLItem.getLabel()+"#");
        
        if(TLItem.isSelected()){
            holder.label.setBackgroundResource(R.drawable.shape_roundrect_label_selected);
        }else{
            holder.label.setBackgroundResource(R.drawable.shape_roundrect_label_normal);
        }

        if (clickTemp == position) {
            if(TLItem.isSelected()){
                holder.label.setBackgroundResource(R.drawable.shape_roundrect_label_normal);
                TLItem.setSelected(false);
            }else{
                holder.label.setBackgroundResource(R.drawable.shape_roundrect_label_selected);
                TLItem.setSelected(true);
            }
            
        }
        return convertView;
    }
    
    static class ViewHolder {

        TextView label;

    }
    public void setShowItems(ArrayList<TalentLableItem> items) {
        this.items =items;
        notifyDataSetChanged();
        
    }
    public ArrayList<TalentLableItem> getItems() {
        return items;
        
    }

    public void setSeclection(int position) {
        // TODO Auto-generated method stub
        clickTemp = position;
        
    }

}

具體什麼問題那?

類似這篇部落格的問題 http://my.oschina.net/u/559701/blog/110945 Android GridVIew position=0重複載入的問題


這個問題在資料顯示方面可能不會帶來太大問題,但是在進行點選互動的時候就會帶來很大問題,通過log列印的方式,我們看到如上效果

找了半天也沒找打特別合適的方法,最後還是決定使用強大的RecyclerView進行重構,與時俱進