Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [Android]仿京東手機端類別頁

[Android]仿京東手機端類別頁

編輯:關於Android編程

[Android]仿京東手機端類別頁

京東手機端的類別標簽頁, 是一個左側滑動可選擇類別, 右側一個類別明細的列表聯動頁面. 當用戶選擇左側選項, 可在右側顯示更多選項來選擇. 實現方式也不少. 最常見的當然是左側和右側各一個Fragment, 左側Fragment放置ListView, 右側放顯示類別明細的Fragment. 如果覺得頁面包含的Fragment太多, 左側直接給一個ListView就可以了.不影響效果.

效果圖:

預覽圖

例子中值得注意的三點:

左側列表點擊某個Item可以自動上下滑動,使所點擊的item自動移至列表中間 點擊item後保留背景色不變 右側布局

針對上面三個點,這裡采取如下的解決方法:

計算可見列表的可見首項或末項position值,使用smoothScrollToPosition()方法實現滑動 自定義列表selectZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcrC0z8K6zcvJv6q1xLGzvrDJqyzU2mFkYXB0ZXLIpbj80MKyor/Y1sZpdGVttcSxs76wyasg09Ky4LK8vtYsssnTw0ZyYWdtZW50ysfX7rrDtcQuIMDvw+bKudPDU2Nyb2xsVmlld9ew1NjL+dPQyv2+3Sy/ydLUtq/MrLXEYWRkVmlldygpLHJlbW92ZVZpZXcoKSwgzfi48bK8vtbKudPDR3JpZFZpZXcuINPJ09pGcmFnbWVudCwgy/nS1Lj80MLK/b7dus24/NDCVmlld7a8t8ezo7e9seMsIMv50tTA/dfT1tDWsb3T08O+ssys0rPD5sSjxOLK/b7dwcsuDQo8cD7W2NTazai5/bzytaW1xMD919O94srN1eLW1sq1z9bLvMK3LCC1sci7yrXP1rK7ysfOqNK7tcQuPC9wPg0KPHA+yLu68yzO0sPHz8jAtMSjxOLT0rLgtcRGcmFnbWVudMr9vt0s0ru/tL7Ntq61xLT6wus6PC9wPg0KPHByZSBjbGFzcz0="brush:java;"> public class JDFragment extends Fragment{ String TAG = JDFragment; private View rootView = null; private LinearLayout llayout_main = null; private TextView tv = null; private LinearLayout.LayoutParams lp_gd = null; private LinearLayout.LayoutParams lp_tv = null; private ArrayList itemList = null; private GDAdapter adapter = null; @Override public void onAttach(Activity activity) { Log.e(TAG, onAttach...); super.onAttach(activity); } @Override public void onCreate(Bundle savedInstanceState) { Log.e(TAG, onCreate...); super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.e(TAG, onCreateView...); rootView = inflater.inflate(R.layout.jd_frg_main, null); llayout_main = (LinearLayout) rootView.findViewById(R.id.llayout_jd_frg_main); tv = (TextView) rootView.findViewById(R.id.tv_jd_frg_main); updateTitle(); //模擬數據 for(int i=0; i<2; i++) { setData(); } return rootView; } protected void updateTitle() { if(getArguments() != null) { updateTitle(getArguments().getString(name)); } } protected void updateTitle(String title) { if(tv != null) { tv.setText(title); } } private void setData() { if(itemList == null) { itemList = new ArrayList(); for(int i=1; i<11; i++) { itemList.add(new Category(選項 + i, +i)); } } //高度60dp+行距8dp = 68dp int heightUnit = (int)TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 68, getResources().getDisplayMetrics()); int height; //計算Gridview總高度 if(itemList.size() % 3 == 0) { height = (itemList.size()/3 + 2)*heightUnit; } else{ height = (itemList.size()/3 + 1)*heightUnit; } if(lp_gd == null) lp_gd = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, height); if(lp_tv == null) lp_tv = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT , (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP , 30, getResources().getDisplayMetrics())); TextView tv_title = new TextView(getActivity()); tv_title.setLayoutParams(lp_tv); tv_title.setText(組一); llayout_main.addView(tv_title); GridView gridView = new GridView(getActivity()); gridView.setNumColumns(3); gridView.setVerticalSpacing(8); gridView.setLayoutParams(lp_gd); adapter = new GDAdapter(getActivity(), itemList,R.drawable.cate); gridView.setAdapter(adapter); llayout_main.addView(gridView); } @Override public void onActivityCreated(Bundle savedInstanceState) { Log.e(TAG, onActivityCreated...); super.onActivityCreated(savedInstanceState); } @Override public void onStart() { Log.e(TAG, onStart...); super.onStart(); } @Override public void onResume() { Log.e(TAG, onResume...); super.onResume(); } @Override public void onPause() { Log.e(TAG, onPause...); super.onPause(); } @Override public void onStop() { Log.e(TAG, onStop...); super.onStop(); } @Override public void onDestroyView() { Log.e(TAG, onDestroyView...); super.onDestroyView(); } @Override public void onDestroy() { Log.e(TAG, onDestroy...); super.onDestroy(); } @Override public void onDetach() { Log.e(TAG, onDetach...); super.onDetach(); } static class GDAdapter extends BaseAdapter { Context context; List results; int imageId; ViewHolder holder = null; public GDAdapter(Context context, List results,int imageId) { this.context = context; this.results = results; this.imageId = imageId; } @Override public int getCount() { // TODO Auto-generated method stub return results.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return results.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Category c = (Category)getItem(position); if(convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(context).inflate(R.layout.jd_item, null); holder.tv = (TextView) convertView.findViewById(R.id.tv_jd_item); holder.imv = (ImageView) convertView.findViewById(R.id.imv_jd_item); } else { holder = (ViewHolder) convertView.getTag(); } convertView.setTag(holder); holder.tv.setText(c.getName()); holder.imv.setImageResource(imageId); return convertView; } class ViewHolder { TextView tv; ImageView imv; } } }

JDFragment的布局文件, jd_frg_main.xml:



    
    
        
    


將所有數據放在ScrollView的線性布局中,使用Fragment作為容器, 可以根據需要ADD, Remove和Update數據和View. 到這裡右側頁面的簡單模擬實現就結束了,都是一目了然的代碼.

然後就是實現左側列表了,先是列表中簡單的自定義Adapter, MyAdapter:

public class MyAdapter extends BaseAdapter
{
    private Context context;
    private List results;
    private int imageId;
    private ViewHolder holder = null;
    private int selectedId;

    public MyAdapter(Context context, List results,int imageId) {
        this.context = context;
        this.results = results;
        this.imageId = imageId;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return results.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return results.get(position);
    }


    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public void setSelected(int position)
    {
        this.selectedId = position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Category c = (Category)getItem(position);

        if(convertView == null)
        {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.jd_item, null);
            holder.tv = (TextView) convertView.findViewById(R.id.tv_jd_item);
            holder.imv = (ImageView) convertView.findViewById(R.id.imv_jd_item);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }

        if(position == selectedId)
        {
            convertView.setBackgroundResource(R.drawable.sele_true);
        }
        else
        {
            convertView.setBackgroundResource(R.drawable.sele_false);
        }

        holder.tv.setText(c.getName());
        holder.imv.setImageResource(imageId);
        convertView.setTag(holder);

        return convertView;
    }

    class ViewHolder
    {
        TextView tv;
        ImageView imv;
    }
}

然後是主Activity了, 在裡面對可見ListView的item位置進行計算, 並進行滑動處理. 當用戶點擊偏上的item, 列表就往下滑動, 加載頂部更多的item; 當用戶點擊偏下的item, 列表就往上滑動, 加載底部更多的item.

同時我們自定義按下和松開時的背景文件放在drawable, 隨便一個shape就可以了. 然後點擊某個item的position時, 在adapter中判斷是否目標item, 是就設置按下背景色 - 白色, 否則就是正常的背景色 - 灰色.

/**
 * 仿京東類別頁
 * @author AlexTam
 */
public class JDActivity extends FragmentActivity{
    private ListView lv_main = null;
    private EditText et_search = null;

    private ArrayList itemList = new ArrayList(); 
    private MyAdapter adapter = null;
    //可見列表項的數量
    private int visibleCount = 0;
    //上次點擊的位置
    private int lastPosition = 0;
    private int ce = 0;
    //實際列表是否超出屏幕
    private boolean isOut = true;
    private JDFragment fragment = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.jd_main);

        init();
    }


    private void init()
    {
        lv_main = (ListView) findViewById(R.id.lv_main);
        et_search = (EditText) findViewById(R.id.et_search);

        for(int i=1; i<21; i++)
        {
            itemList.add(new Category(選項  + i, +i));
        }

        adapter = new MyAdapter(this, itemList,R.drawable.ic_launcher);
        lv_main.setAdapter(adapter);
        lv_main.setOnItemClickListener(new MyOnItemOnClick());
        lv_main.setSelector(R.color.pink);

        //模擬右側標簽頁
        fragment = new JDFragment();
        Bundle bundle = new Bundle();
        bundle.putString(name, c1);
        fragment.setArguments(bundle);
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.flayout_main, fragment, c0).commit();

        adapter.setSelected(0);
        adapter.notifyDataSetChanged();
    }

    private class MyOnItemOnClick implements OnItemClickListener
    {
        @Override
        public void onItemClick(AdapterView parent, View view, int position,
                long id) 
        {
            //計算滑動
            if(visibleCount == 0)
            {
                visibleCount = lv_main.getChildCount();
                if(visibleCount == itemList.size())
                    isOut = false;
                else
                {
                    ce = visibleCount/2;
                }
            }

            if(position <= (parent.getFirstVisiblePosition() + ce))
            {   //上移
                lv_main.smoothScrollToPosition(position - ce);
            }
            else
            {   //下移
                if((parent.getLastVisiblePosition() + ce + 1) <= parent.getCount())
                {
                    lv_main.smoothScrollToPosition(position + ce);
                }
                else
                {
                    lv_main.smoothScrollToPosition(parent.getCount()-1);
                }

            }

            lastPosition = position;

            adapter.setSelected(position);
            adapter.notifyDataSetChanged();

            //更新右側標簽頁的標題
            fragment.updateTitle(c + (position+1));
        }

    }


    /**
     * 選項對象
     */
    static class Category
    {
        private String name;
        private String id;

        Category(String name,String id)
        {
            this.name = name;
            this.id = id;
        }

        public String getName()
        {
            return this.name;
        }
    }



}

OK, 到此效果就出來了. 好簡單吧!

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved