国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿京東手機端類別頁

2019-10-22 18:15:12
字體:
來源:轉載
供稿:網友

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

效果圖:

Android,京東,手機端,類別頁

例子中值得注意的三點:

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

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

  • 計算可見列表的可見首項或末項position值,使用smoothScrollToPosition()方法實現滑動
  • 自定義列表selector按下和松開的背景色,在adapter去更新并控制item的背景色
  • 右側布局,采用Fragment是最好的. 里面使用ScrollView裝載所有數據,可以動態的addView(),removeView(), 網格布局使用GridView. 由于Fragment, 所以更新數據和更新View都非常方便, 所以例子中直接用靜態頁面模擬數據了.

重在通過簡單的例子解釋這種實現思路, 當然實現不是唯一的.

然后,我們先來模擬右側的Fragment數據,一看就懂的代碼:

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<Category> 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<Category>();      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<Category> results;    int imageId;    ViewHolder holder = null;    public GDAdapter(Context context, List<Category> 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:

<?xml version="1.0" encoding="utf-8" ?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="#FFFFFF"  >  <TextView     android:id="@+id/tv_jd_frg_main"    android:layout_width="match_parent"    android:layout_height="25dp"    android:text="Fragment"    android:textSize="16sp"    android:background="#EEEEEE"    />  <ScrollView     android:id="@+id/scrlayout_jd_frg_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:layout_below="@+id/tv_jd_frg_main"    android:overScrollMode="never"    >    <LinearLayout       android:id="@+id/llayout_jd_frg_main"      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:orientation="vertical"      />  </ScrollView></RelativeLayout>

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

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

public class MyAdapter extends BaseAdapter{  private Context context;  private List<Category> results;  private int imageId;  private ViewHolder holder = null;  private int selectedId;  public MyAdapter(Context context, List<Category> 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<Category> itemList = new ArrayList<Category>();   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, 到此效果就出來了. 好簡單吧!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 英山县| 开平市| 麻栗坡县| 调兵山市| 鄂伦春自治旗| 潢川县| 宜宾县| 南阳市| 含山县| 梅州市| 新宁县| 温泉县| 合作市| 榆林市| 灵台县| 泸西县| 永靖县| 青岛市| 额尔古纳市| 揭阳市| 宁陵县| 于田县| 保康县| 和平区| 黄平县| 正定县| 乌苏市| 拉孜县| 弥勒县| 綦江县| 蓬安县| 宜兴市| 崇明县| 安阳市| 五莲县| 元阳县| 贵德县| 武鸣县| 铁力市| 陕西省| 临西县|