上图就是真小米商城的基本Ui以及整体框架页面
首先我们先看整体框架吧!
有底部菜单栏,说明每一个按钮将会对应一个页面,这个我们就用最简单的方式ViewPager(嵌套Fragment)+RadioGroup(嵌套RadioButton)实现吧!而且整体页面是不可滑动的,只能点击底部菜单栏来实现页面切换,下面我们来看看如何实现它吧!
首先看眼布局:
以上ViewPager使用的是一个自定义的不可滑动的ViewPager,我们看看怎么怎么自定义的
public class NoScrollViewPage extends ViewPager {
private boolean isPagingEnabled = false;
public NoScrollViewPage(Context context) {
super(context);
}
public NoScrollViewPage(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onInterceptTouchEvent(event);
}
实现以上代码,就可实现不可滑动。下面我们就来看看实现代码吧!
public class HomeActivity extends AppCompatActivity {
private NoScrollViewPage middleVp;
private RadioButton homeRb;
private RadioButton categoryRb;
private RadioButton discoverRb;
private RadioButton shopcarRb;
private RadioButton mineRb;
private RadioGroup radioRg;
private List fragments = new ArrayList<>();
private FragmentAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_home);
initView();
downData();
}
private void downData() {
//向数据源内添加数据
fragments.add(new HomeFragment());
fragments.add(new CategoryFragment());
fragments.add(new DiscoverFragment());
fragments.add(new ShopcarFragment());
fragments.add(new MineFragment());
//ViewPager适配器
adapter = new FragmentAdapter(getSupportFragmentManager(), fragments);
middleVp.setAdapter(adapter);
//viewPager的点击事件
middleVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
RadioButton childAt = (RadioButton) radioRg.getChildAt(position);
childAt.setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
//RadioGroup的点击事件
radioRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i){
case R.id.home_rb:
middleVp.setCurrentItem(0);
break;
case R.id.category_rb:
middleVp.setCurrentItem(1);
break;
case R.id.discover_rb:
middleVp.setCurrentItem(2);
break;
case R.id.shopcar_rb:
middleVp.setCurrentItem(3);
break;
case R.id.mine_rb:
middleVp.setCurrentItem(4);
break;
}
}
});
}
//初始化控件
private void initView() {
middleVp = (NoScrollViewPage) findViewById(R.id.middle_vp);
homeRb = (RadioButton) findViewById(R.id.home_rb);
categoryRb = (RadioButton) findViewById(R.id.category_rb);
discoverRb = (RadioButton) findViewById(R.id.discover_rb);
shopcarRb = (RadioButton) findViewById(R.id.shopcar_rb);
mineRb = (RadioButton) findViewById(R.id.mine_rb);
radioRg = (RadioGroup) findViewById(R.id.radio_rg);
}
}
这样就实现了点击页面跳转,接下来我看看看首页内部结构吧:
它是一个可滑动的标签,每个标签都对应着一个页面,那我们现在就来实现它:
我使用的是disgin包下的TabLayout
布局:
headView是一个自定义的一个类,里面只是而已,我们来看看
布局:
代码:
public class HeadView extends LinearLayout implements View.OnClickListener {
public SearchView searchView;
private OnScanAndVoiceListener listener;
public ImageView scanImg;
public HeadView(Context context) {
this(context, null);
}
public HeadView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public HeadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.head_layout, this);
searchView = (SearchView) findViewById(R.id.search);
scanImg = (ImageView) findViewById(R.id.scan_iv);
ImageView message = (ImageView) findViewById(R.id.message_iv);
scanImg.setOnClickListener(this);
message.setOnClickListener(this);
}
public void setOnQueryTextListener(SearchView.OnQueryTextListener listener) {
searchView.setOnQueryTextListener(listener);
}
public void setOnScanAndSpeakListener(OnScanAndVoiceListener listener) {
this.listener = listener;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.scan_iv:
listener.startScanner();
break;
case R.id.message_iv:
listener.startSpeak();
break;
}
}
}
创建一个接口
public interface OnScanAndVoiceListener {
/**
* 扫描回调
*/
void startScanner();
/**
* 语音回调
*/
void startSpeak();
}
顶部搜索框扫一扫,消息,就是这样,我们继续看看推荐页代码:
public class HomeFragment extends Fragment implements OnScanAndVoiceListener {
private View view;
private TabLayout tab_tl;
private ViewPager viewPager;
private String path = "http://169.254.164.79:8080/word/xiaomijson.json";
private List middleList = new ArrayList<>();
private String[] titles = {"推荐", "手机", "智能", "电视5周年", "笔记本", "家电", "新款游戏本", "大内存手机", "全面屏", "生活周边", "盒子"};
//当标签数目小于等于4个时,标签栏不可滑动
public static final int MOVABLE_COUNT = 4;
private HeadView head_view;
public HomeFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home, container, false);
initView(view);
FragmentData(view);
return view;
}
private void FragmentData(View view) {
//每次进入前数据源一定要清空,不然一定会造成下标越界的后果
middleList.clear();
middleList.add(new RecommendFragment());
middleList.add(new PhoneFragment());
middleList.add(new CapacityFragment());
middleList.add(new AnniversaryFragment());
middleList.add(new JotterFragment());
middleList.add(new ApplianceFragment());
middleList.add(new NewstyleFragment());
middleList.add(new MemoryFragment());
middleList.add(new OverallFragment());
middleList.add(new RimFragment());
middleList.add(new BoxFragment());
Log.e("FragmentData", titles.length + "");
/**
* 首先这个是Fragment嵌套Fragment,如果使用getSupportFragmentmanager
* 会导致数据加载不出来只能切换界面再切换回来,数据才会展示,如此我们就是用
* getChildFragmentManager
* 这就相当一个子管理者,专门处理Fragment嵌套Fragment出现的问题
*/
MiddleAdapter adapter = new MiddleAdapter(this.getChildFragmentManager(), middleList, titles);
viewPager.setAdapter(adapter);
int length = titles.length;
//MODE_FIXED标签栏不可滑动,各个标签会平分屏幕的宽度
tab_tl.setTabMode(length <= MOVABLE_COUNT ? TabLayout.MODE_FIXED : TabLayout.MODE_SCROLLABLE);
//指示条的颜色
tab_tl.setSelectedTabIndicatorColor(getResources().getColor(android.R.color.holo_orange_dark));
// tab_tl.setSelectedTabIndicatorHeight((int) getResources().getDimension(R.dimen.indicatorHeight));
//关联tabLayout和ViewPager,两者的选择和滑动状态会相互影响
tab_tl.setupWithViewPager(viewPager);
}
private void initView(View view) {
tab_tl = (TabLayout) view.findViewById(R.id.tab_tl);
viewPager = (ViewPager) view.findViewById(R.id.viewPager);
head_view = (HeadView) view.findViewById(R.id.head_view);
}
@Override
public void startScanner() {
}
@Override
public void startSpeak() {
}
}
这就实现内部可滑动的标签,以及它的对应页面,现在我们就往内部填放数据吧:
public class RecommendFragment extends Fragment implements OnScanAndVoiceListener {
private Banner banner_a;
private ImageView fake_iv;
private ImageView image_iv;
private RecyclerView recycler;
private String path = "http://192.168.0.108:8080/word/home_mi.json";
private List HorizontalList = new ArrayList<>();
private List listEntities = new ArrayList<>();
private List bannerList = new ArrayList<>();
private RecyclerAdapter adapter;
private long aLong = 1000;
private MyDiskLruCache myDiskLruCache;
private TextView hour_tv;
private TextView minute_tv;
private TextView second_tv;
private Timer timer;
@SuppressLint("HandlerLeak")
Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
List banners = (List) msg.obj;
bannerList.addAll(banners);
banner_a.setBannerStyle(BannerConfig.CIRCLE_INDICATOR).setImages(bannerList).setImageLoader(new ImageLoader() {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(getActivity()).load(path).into(imageView);
}
}).setDelayTime(3000).setIndicatorGravity(BannerConfig.RIGHT).start();
} else if (msg.what == 2) {
long miao = (long) msg.obj;
time2Data(miao);
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recommend, container, false);
myDiskLruCache = new MyDiskLruCache(getContext());
initView(view);
getHttp(path);
// bannerData(view);
ArrayData();
timeData();
return view;
}
private void timeData() {
new Thread(new Runnable() {
@Override
public void run() {
for (long i = aLong; i >= 0; i--) {
Message message = handler.obtainMessage();
message.what = 2;
message.obj = i;
handler.sendMessage(message);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
private void time2Data(long miao) {
if (miao > 0) {
String formatLongToTimeStr = formatLongToTimeStr(miao);
String[] split = formatLongToTimeStr.split(":");
for (int i = 0; i < split.length; i++) {
if (i == 0) {
if (Integer.valueOf(split[0]) < 10) {
hour_tv.setText("0" + split[0] + "");
} else {
hour_tv.setText(split[0] + "");
}
}
if (i == 1) {
if (Integer.valueOf(split[1]) < 10) {
minute_tv.setText("0" + split[1] + "");
} else {
minute_tv.setText(split[1] + "");
}
}
if (i == 2) {
if (Integer.valueOf(split[2]) < 10) {
second_tv.setText("0" + split[2] + "");
} else {
second_tv.setText(split[2] + "");
}
}
}
}
}
private String formatLongToTimeStr(Long l) {
int hour = 0;
int minute = 0;
int second = 0;
String strtime = null;
second = l.intValue();
if (second > 60) {
minute = second / 60; //取整
second = second % 60; //取余
}
if (minute > 60) {
hour = minute / 60;
minute = minute % 60;
}
strtime = hour + ":" + minute + ":" + second;
return strtime;
}
private void ArrayData() {
Log.i("TAG", "iflashbuys======" + HorizontalList.size());
adapter = new RecyclerAdapter(getContext(), HorizontalList);
recycler.setAdapter(adapter);
}
private void bannerData(View view) {
//设置banner样式
banner_a.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
//设置图片加载器
banner_a.setImageLoader(new ImageLoader() {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(context).load(path).into(imageView);
}
});
//设置图片集合
Log.i("TAG", "setImages======" + bannerList.size());
banner_a.setImages(bannerList);
//设置自动轮播,默认为true
banner_a.isAutoPlay(true);
//设置轮播时间
banner_a.setDelayTime(3000);
//设置指示器位置
banner_a.setIndicatorGravity(BannerConfig.RIGHT);
}
private void getHttp(String url) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().get().url(path).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
MemoryCache memoryCache = new MemoryCache();
String cacheData = memoryCache.getCacheData(path);
Log.i("getCacheData",cacheData+"");
if (cacheData != null) {
Log.i("TAG","数据是从内存获取到的");
//从内存获取数据
initData(cacheData);
} else {
//从硬盘获取数据
Log.i("TAG","数据是从硬盘获取到的");
try {
InputStream data = myDiskLruCache.getCacheData(path);
String result = new String(ByteStreams.toByteArray(data));
initData(result);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//存入数据
MyDiskLruCache myDiskLruCache = new MyDiskLruCache(getContext());
myDiskLruCache.saveCacheData(path);
String string = response.body().string();
MemoryCache memoryCache = new MemoryCache();
memoryCache.saveCacheData(path, string);
//Okhttp框架解析
initData(string);
}
});
}
private void initData(String string) {
Message message = new Message();
List banners = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(string);
int code = jsonObject.optInt("code");
JSONObject jsonData = jsonObject.optJSONObject("data");
//获取Banner填充数据
JSONArray jsonBanners = jsonData.optJSONArray("banner");
for (int i = 0; i < jsonBanners.length(); i++) {
String imgUrl = jsonBanners.optString(i);
banners.add(imgUrl);
}
message.what = 1;
message.obj = banners;
handler.sendMessage(message);
//获取横向列表滑动数据
JSONArray jsonHorObj = jsonData.optJSONArray("horizontal_list");
for (int i = 0; i < jsonHorObj.length(); i++) {
JSONObject jObj = jsonHorObj.optJSONObject(i);
HomeBean.DataEntity.HorizontalListEntity entity = new HomeBean.DataEntity.HorizontalListEntity();
// TODO 加入参数
entity.setImg_url(jObj.optString("img_url"));
entity.setProduct_name(jObj.optString("product_name"));
entity.setProduct_org_price(jObj.optString("product_org_price"));
entity.setProduct_price(jObj.optString("product_price"));
//为数据源赋值
HorizontalList.add(entity);
}
JSONArray jsonListObj = jsonData.optJSONArray("list");
for (int i = 0; i < jsonListObj.length(); i++) {
JSONObject listObj = jsonListObj.optJSONObject(i);
HomeBean.DataEntity.ListEntity listEntity = new HomeBean.DataEntity.ListEntity();
listEntity.setImg_url(listObj.optString("img_url"));
listEntity.setProduct_name(listObj.optString("product_name"));
listEntity.setProduct_price(listObj.optString("product_price"));
listEntity.setProduct_org_price(listObj.optString("product_org_price"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void initView(View view) {
banner_a = (Banner) view.findViewById(R.id.banner_a);
fake_iv = (ImageView) view.findViewById(R.id.fake_iv);
image_iv = (ImageView) view.findViewById(R.id.image_iv);
recycler = (RecyclerView) view.findViewById(R.id.recycler);
LinearLayoutManager manager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
recycler.setLayoutManager(manager);
hour_tv = (TextView) view.findViewById(R.id.hour_tv);
minute_tv = (TextView) view.findViewById(R.id.minute_tv);
second_tv = (TextView) view.findViewById(R.id.second_tv);
}
@Override
public void onStart() {
super.onStart();
//开始轮播
banner_a.start();
}
@Override
public void onStop() {
super.onStop();
//接收轮播
banner_a.stopAutoPlay();
}
@Override
public void startScanner() {
}
@Override
public void startSpeak() {
}
}
接下来,我们看看分类页面的布局以及代码实现:
布局
是不是觉得很眼熟,一个Tablayout,一个ViewPager,只不过都是自定义的,VerticalTagLayout是第三方写好的一个控件,添加依赖:
implementation 'q.rorbin:VerticalTabLayout:1.2.5'即可,
VerticalPager则需要自己定义,代码如下:
public class VerticalPager extends ViewPager {
private OnItemClickListener mOnItemClickListener;
public VerticalPager(Context context) {
super(context);
init();
}
public VerticalPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
setup();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
private float scaleY;
@Override
public boolean onTouchEvent(MotionEvent ev) {
System.out.println("----------getY" + ev.getY());
System.out.println("----------scaleY" + scaleY);
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
}
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
scaleY = ev.getY();
}
if (ev.getAction() == MotionEvent.ACTION_UP) {
if (scaleY == ev.getY()) {
System.out.println("------------------======");
scaleY = 0;
return false;
}
}
try {
return super.onTouchEvent(swapXY(ev));
} catch (Exception e) {
}
return true;
}
// 点击事件
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
private void setup() {
final GestureDetector tapGestureDetector = new GestureDetector(getContext(), new TapGestureListener());
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
tapGestureDetector.onTouchEvent(event);
return false;
}
});
}
private class TapGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(getCurrentItem());
}
return true;
}
}
好了,这样UI就搭建完成,看看实现代码:
public class CategoryFragment extends Fragment {
private View view;
private List datas=new ArrayList<>();
private VerticalTabLayout tablayout;
private VerticalPager viewpager;
private VpAdapter adapter;
public CategoryFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_category, container, false);
initView(view);
loadData();
return view;
}
private void loadData() {
datas.clear();
datas.add("新品");
datas.add("手机");
datas.add("电视");
datas.add("电脑");
datas.add("家电");
datas.add("路由");
datas.add("出行");
datas.add("穿戴");
datas.add("智能");
datas.add("电源");
datas.add("个护");
datas.add("灯具");
datas.add("儿童");
datas.add("插线板");
datas.add("音频");
datas.add("箱包");
datas.add("生活");
datas.add("配件");
datas.add("家装");
datas.add("礼品");
datas.add("服务");
datas.add("米粉卡");
datas.add("零售店");
//适配器
adapter = new VpAdapter(getChildFragmentManager());
viewpager.setAdapter(adapter);
//进行关联
tablayout.setupWithViewPager(viewpager);
}
private void initView(View view) {
tablayout = (VerticalTabLayout) view.findViewById(R.id.tablayout);
viewpager = (VerticalPager) view.findViewById(R.id.viewpager);
}
// 自定义适配器
class VpAdapter extends FragmentPagerAdapter {
public VpAdapter(FragmentManager fm) {
super(fm);
}
//返回选项卡的文本 ,,,添加选项卡
@Override
public CharSequence getPageTitle(int position) {
return datas.get(position);
}
//动态创建fragment对象并返回
@Override
public Fragment getItem(int position) {
// 创建布局
ProductFragment vcount = new ProductFragment();
// Bundle bundle = new Bundle();
//// 放入值
// bundle.putString("name", datas.get(position));
//// 放入布局文件中
// vcount.setArguments(bundle);
return vcount;
}
//返回数量
@Override
public int getCount() {
return datas.size();
}
这样就实现了分类页竖向滑动标签,竖向滑动的ViewPager。
接下来就是我们的发现页了,最上方是一个滚动轮播图,下方是一个网格式列表:
布局:
代码:
public class DiscoverFragment extends Fragment {
private View inflate;
private Banner discover_bn;
private RecyclerView myRecycler;
private List cars = new ArrayList<>();
private ScrollView scrollView;
private String path = "";
private View header;
public DiscoverFragment() {
// Required empty public constructor
}
@SuppressLint("ClickableViewAccessibility")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
inflate = inflater.inflate(R.layout.fragment_discover, container, false);
initView(inflate);
BannerData();
ListData();
return inflate;
}
private void ListData() {
cars.clear();
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().get().url(path).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String string = response.body().string();
Gson gson = new Gson();
DiscoverBean bean = gson.fromJson(string, DiscoverBean.class);
cars.addAll(bean.getResult().getList());
Log.i("DiscoverFragment",cars.get(0).toString());
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i("DiscoverFragment",cars.get(0).getTitle());
DiscoverAdapter adapter = new DiscoverAdapter(getContext(),cars);
myRecycler.setAdapter(adapter);
adapter.addHeaderView(header);
}
});
}
});
}
private void BannerData() {
//设置Banner显示样式
discover_bn.setBannerStyle(BannerConfig.NUM_INDICATOR);
//设置Banner图片集合
discover_bn.setImages(ImageData());
//设置图片加载器
discover_bn.setImageLoader(new ImageLoader() {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(context).load(path).into(imageView);
}
});
//设置自动轮播
discover_bn.isAutoPlay(true);
//设置轮播时间
discover_bn.setDelayTime(3000);
//设置指示器位置
discover_bn.setIndicatorGravity(BannerConfig.RIGHT);
}
private List ImageData() {
List imageList = new ArrayList<>();
imageList.add("https://club2.autoimg.cn/album/g28/M02/19/62/userphotos/2018/09/11/10/ChcCR1uXI56AJYLTAASQBra5Ma0257.jpg");
imageList.add("https://club2.autoimg.cn/album/g26/M04/D3/E4/userphotos/2018/08/28/09/ChsEe1uEptGAeR_VAAXAbdRZlxg254.jpg");
imageList.add("https://club2.autoimg.cn/album/g1/M0A/B7/DC/userphotos/2018/09/03/10/ChsEj1uMonaAfLKhAAWHLF4Kw7c659.jpg");
imageList.add("https://club2.autoimg.cn/album/g1/M0A/82/06/userphotos/2018/08/22/16/ChcCQ1t9I0uAVm8lAARLaOznUFA233.jpg");
imageList.add("https://club2.autoimg.cn/album/g28/M03/E1/07/userphotos/2018/08/29/19/ChsEfVuGgrSATWzhAAFDTgN9xZ8696.jpg");
return imageList;
}
private void initView(View inflate) {
myRecycler = (RecyclerView) inflate.findViewById(R.id.myRecycler);
// myRecycler.setHasFixedSize(true);
// myRecycler.setNestedScrollingEnabled(false);
GridLayoutManager manager = new GridLayoutManager(getContext(), 3);
//设置不同大小的网格列表
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (3 - position % 3);
}
});
myRecycler.setLayoutManager(manager);
header = LayoutInflater.from(getContext()).inflate(R.layout.header_layout, null);
discover_bn = (Banner) header.findViewById(R.id.discover_bn);
}
@Override
public void onStart() {
super.onStart();
//开始轮播
discover_bn.start();
}
@Override
public void onStop() {
super.onStop();
//接收轮播
discover_bn.stopAutoPlay();
}
下面我们看一看购物车的实现吧!
布局
title_layout
实现代码:
public class ShopcarFragment extends Fragment implements CheckInterface,ModifyCountInterface,View.OnClickListener{
private View inflate;
private TextView tv_title;
private TextView bt_header_right;
private ImageView message_title;
private ListView shoppingLv;
private CheckBox ck_all;
private TextView tv_show_price;
private TextView tv_settlement;
private LinearLayout rl_bottom;
private List shoppingList=new ArrayList<>();
private ShoppingCartAdapter adapter;
private int totalCount=0;
private double totalPrice=0.00;
private boolean flag=false;
public ShopcarFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
inflate = inflater.inflate(R.layout.fragment_shopcar, container, false);
initView(inflate);
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(getContext()));
initData();
return inflate;
}
private void initView(View inflate) {
bt_header_right = (TextView) inflate.findViewById(R.id.bt_header_right);
shoppingLv = (ListView) inflate.findViewById(R.id.shopping_list);
ck_all = (CheckBox) inflate.findViewById(R.id.ck_all);
tv_show_price = (TextView) inflate.findViewById(R.id.tv_show_price);
tv_settlement = (TextView) inflate.findViewById(R.id.tv_settlement);
rl_bottom = (LinearLayout) inflate.findViewById(R.id.rl_bottom);
bt_header_right.setOnClickListener(this);
ck_all.setOnClickListener(this);
tv_settlement.setOnClickListener(this);
}
private void initData() {
for (int i = 0; i < 3; i++) {
ShoppingCartBean shoppingCartBean = new ShoppingCartBean();
shoppingCartBean.setShoppingName("小米8 6GB+64GB\n" +
"全球首款双频GPS,骁龙845处理器");
shoppingCartBean.setDressSize(10);
shoppingCartBean.setId(i);
shoppingCartBean.setPrice(2599);
shoppingCartBean.setCount(1);
shoppingCartBean.setImageUrl("https://i1.mifile.cn/a1/pms_1528092587.49664451!220x220.jpg");
shoppingList.add(shoppingCartBean);
}
for (int i = 0; i < 4; i++) {
ShoppingCartBean shoppingCartBean = new ShoppingCartBean();
shoppingCartBean.setShoppingName("小米MIX 2S\n陶瓷机身 手机中的艺术品");
shoppingCartBean.setAttribute("黑白色");
shoppingCartBean.setPrice(3599);
shoppingCartBean.setId(i+2);
shoppingCartBean.setCount(3);
shoppingCartBean.setImageUrl("https://i1.mifile.cn/a1/pms_1522034061.12391230!220x220.jpg");
shoppingList.add(shoppingCartBean);
}
adapter = new ShoppingCartAdapter(getContext(),shoppingList);
adapter.setCheckInterface(this);
adapter.setModifyCountInterface(this);
shoppingLv.setAdapter(adapter);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
//全选按钮
case R.id.ck_all:
if (shoppingList.size() != 0) {
if (ck_all.isChecked()) {
for (int i = 0; i < shoppingList.size(); i++) {
shoppingList.get(i).setChoosed(true);
}
adapter.notifyDataSetChanged();
} else {
for (int i = 0; i < shoppingList.size(); i++) {
shoppingList.get(i).setChoosed(false);
}
adapter.notifyDataSetChanged();
}
}
statistics();
break;
case R.id.bt_header_right:
flag = !flag;
if (flag) {
bt_header_right.setText("完成");
adapter.isShow(false);
} else {
bt_header_right.setText("编辑");
adapter.isShow(true);
}
break;
case R.id.tv_settlement: //结算
lementOnder();
break;
}
}
/**
* 结算订单、支付
*/
private void lementOnder() {
//选中的需要提交的商品清单
for (ShoppingCartBean bean:shoppingList ){
boolean choosed = bean.isChoosed();
if (choosed){
String shoppingName = bean.getShoppingName();
int count = bean.getCount();
double price = bean.getPrice();
int size = bean.getDressSize();
String attribute = bean.getAttribute();
int id = bean.getId();
Log.d("ShoppingCartBean",id+"----id---"+shoppingName+"---"+count+"---"+price+"--size----"+size+"--attr---"+attribute);
}
}
ToastUtil.showL(getContext(),"总价:"+totalPrice);
//跳转到支付界面
}
/**
* 单选
* @param position 组元素位置
* @param isChecked 组元素选中与否
*/
@Override
public void checkGroup(int position, boolean isChecked) {
shoppingList.get(position).setChoosed(isChecked);
if (isAllCheck())
ck_all.setChecked(true);
else
ck_all.setChecked(false);
adapter.notifyDataSetChanged();
statistics();
}
/**
* 遍历list集合
* @return
*/
private boolean isAllCheck() {
for (ShoppingCartBean group : shoppingList) {
if (!group.isChoosed())
return false;
}
return true;
}
/**
* 统计操作
* 1.先清空全局计数器
* 2.遍历所有子元素,只要是被选中状态的,就进行相关的计算操作
* 3.给底部的textView进行数据填充
*/
public void statistics() {
totalCount = 0;
totalPrice = 0.00;
for (int i = 0; i < shoppingList.size(); i++) {
ShoppingCartBean shoppingCartBean = shoppingList.get(i);
if (shoppingCartBean.isChoosed()) {
totalCount++;
totalPrice += shoppingCartBean.getPrice() * shoppingCartBean.getCount();
}
}
tv_show_price.setText("合计:" + totalPrice);
tv_settlement.setText("结算(" + totalCount + ")");
}
/**
* 增加
* @param position 组元素位置
* @param showCountView 用于展示变化后数量的View
* @param isChecked 子元素选中与否
*/
@Override
public void doIncrease(int position, View showCountView, boolean isChecked) {
ShoppingCartBean shoppingCartBean = shoppingList.get(position);
int currentCount = shoppingCartBean.getCount();
currentCount++;
shoppingCartBean.setCount(currentCount);
((TextView) showCountView).setText(currentCount + "");
adapter.notifyDataSetChanged();
statistics();
}
/**
* 删减
*
* @param position 组元素位置
* @param showCountView 用于展示变化后数量的View
* @param isChecked 子元素选中与否
*/
@Override
public void doDecrease(int position, View showCountView, boolean isChecked) {
ShoppingCartBean shoppingCartBean = shoppingList.get(position);
int currentCount = shoppingCartBean.getCount();
if (currentCount == 1) {
return;
}
currentCount--;
shoppingCartBean.setCount(currentCount);
((TextView) showCountView).setText(currentCount + "");
adapter.notifyDataSetChanged();
statistics();
}
/**
* 删除
*
* @param position
*/
@Override
public void childDelete(int position) {
shoppingList.remove(position);
adapter.notifyDataSetChanged();
statistics();
}
}
Adapter
public class ShoppingCartAdapter extends BaseAdapter {
private boolean isShow = true;//是否编辑完成
private Context context;
private List shoppingList;
//复选框接口
private CheckInterface checkInterface;
//改变商品数量接口
private ModifyCountInterface modifyCountInterface;
public ShoppingCartAdapter(Context context, List shoppingList) {
this.context = context;
this.shoppingList = shoppingList;
}
/**
* 单选接口
*
* @param checkInterface
*/
public void setCheckInterface(CheckInterface checkInterface) {
this.checkInterface = checkInterface;
}
/**
* 改变商品数量接口
*
* @param modifyCountInterface
*/
public void setModifyCountInterface(ModifyCountInterface modifyCountInterface) {
this.modifyCountInterface = modifyCountInterface;
}
@Override
public int getCount() {
return shoppingList == null ? 0 : shoppingList.size();
}
@Override
public Object getItem(int i) {
return shoppingList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
/**
* 是否显示可编辑
*
* @param flag
*/
public void isShow(boolean flag) {
isShow = flag;
notifyDataSetChanged();
}
@SuppressLint("SetTextI18n")
@Override
public View getView(final int i, View view, ViewGroup viewGroup) {
final ViewHolder holder;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.item_shopping_cart_layout, viewGroup, false);
holder = new ViewHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
final ShoppingCartBean bean = shoppingList.get(i);
boolean choosed = bean.isChoosed();
if (choosed) {
holder.ckOneChose.setChecked(true);
} else {
holder.ckOneChose.setChecked(false);
}
String attribute = bean.getAttribute();
if (!StringUtil.isEmpty(attribute)) {
holder.tvCommodityAttr.setText(attribute);
} else {
holder.tvCommodityAttr.setText(bean.getDressSize() + "");
}
holder.tvCommodityAttr.setText(bean.getShoppingName());
holder.tvCommodityPrice.setText(bean.getPrice() + "");
holder.tvCommodityNum.setText(" X" + bean.getCount() + "");
holder.tvCommodityShowNum.setText(bean.getCount() + "");
ImageLoader.getInstance().displayImage(bean.getImageUrl(), holder.ivShowPic);
//单选按钮
holder.ckOneChose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bean.setChoosed(((CheckBox) view).isChecked());
//向外暴露的接口
checkInterface.checkGroup(i, ((CheckBox) view).isChecked());
}
});
//增加按钮
holder.ivAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//暴露增加接口
modifyCountInterface.doIncrease(i, holder.tvCommodityShowNum, holder.ckOneChose.isChecked());
}
});
//删除按钮
holder.ivSub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//暴露删减接口
modifyCountInterface.doDecrease(i,holder.tvCommodityShowNum,holder.ckOneChose.isChecked());
}
});
//删除弹框
holder.tvCommodityDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog alert = new AlertDialog.Builder(context).create();
alert.setTitle("操作提示");
alert.setMessage("您确定要将这些商品从购物车中移除吗?");
alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//删除 目前只是从item中移除
modifyCountInterface.childDelete(i);
}
});
alert.show();
}
});
//判断是否在编辑状态下
if (isShow) {
holder.tvCommodityName.setVisibility(View.VISIBLE);
holder.rlEdit.setVisibility(View.GONE);
holder.tvCommodityNum.setVisibility(View.VISIBLE);
holder.tvCommodityDelete.setVisibility(View.GONE);
} else {
holder.tvCommodityName.setVisibility(View.VISIBLE);
holder.rlEdit.setVisibility(View.VISIBLE);
holder.tvCommodityNum.setVisibility(View.GONE);
holder.tvCommodityDelete.setVisibility(View.VISIBLE);
}
return view;
}
class ViewHolder {
ImageView ivShowPic, tvCommodityDelete;
TextView tvCommodityName, tvCommodityAttr, tvCommodityPrice, tvCommodityNum, tvCommodityShowNum, ivSub, ivAdd;
CheckBox ckOneChose;
LinearLayout rlEdit;
public ViewHolder(View itemView) {
ckOneChose = (CheckBox) itemView.findViewById(R.id.ck_chose);
ivShowPic = (ImageView) itemView.findViewById(R.id.iv_show_pic);
ivSub = (TextView) itemView.findViewById(R.id.iv_sub);
ivAdd = (TextView) itemView.findViewById(R.id.iv_add);
tvCommodityName = (TextView) itemView.findViewById(R.id.tv_commodity_name);
tvCommodityAttr = (TextView) itemView.findViewById(R.id.tv_commodity_attr);
tvCommodityPrice = (TextView) itemView.findViewById(R.id.tv_commodity_price);
tvCommodityNum = (TextView) itemView.findViewById(R.id.tv_commodity_num);
tvCommodityShowNum = (TextView) itemView.findViewById(R.id.tv_commodity_show_num);
tvCommodityDelete = (ImageView) itemView.findViewById(R.id.tv_commodity_delete);
rlEdit = (LinearLayout) itemView.findViewById(R.id.rl_edit);
}
}
}
下面我们来实现一下我的,也就是个人中心页面,
布局:
实现代码:
public class MineFragment extends Fragment{
private String uri = "https://m.mi.com/user";
private View inflate;
private WebView mine_wv;
private CircleImageView header_mine;
private RadioButton obligation_bt;
private RadioButton receiving_bt;
private RadioButton evaluate_bt;
private RadioButton change_bt;
private ImageView mi_iv;
private LSettingItem discountsLi;
private LSettingItem memberLi;
private LSettingItem walletLi;
private LSettingItem serviceLi;
private LSettingItem milletLi;
private LSettingItem supplyLi;
private LSettingItem moreLi;
private LSettingItem installLi;
public MineFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
inflate = inflater.inflate(R.layout.fragment_mine, container, false);
initView(inflate);
initData();
return inflate;
}
private void initData() {
discountsLi.setmOnLSettingItemClick(new LSettingItem.OnLSettingItemClick() {
@Override
public void click() {
Intent intent=new Intent(getContext(), DiscountsActivity.class);
startActivity(intent);
}
});
}
private void initView(View inflate) {
header_mine = (CircleImageView) inflate.findViewById(R.id.header_mine);
obligation_bt = (RadioButton) inflate.findViewById(R.id.obligation_bt);
receiving_bt = (RadioButton) inflate.findViewById(R.id.receiving_bt);
evaluate_bt = (RadioButton) inflate.findViewById(R.id.evaluate_bt);
change_bt = (RadioButton) inflate.findViewById(R.id.change_bt);
mi_iv = (ImageView) inflate.findViewById(R.id.mi_iv);
discountsLi = (LSettingItem) inflate.findViewById(R.id.discounts);
memberLi = (LSettingItem) inflate.findViewById(R.id.member);
walletLi = (LSettingItem) inflate.findViewById(R.id.wallet);
serviceLi = (LSettingItem) inflate.findViewById(R.id.service);
milletLi = (LSettingItem) inflate.findViewById(R.id.millet);
supplyLi = (LSettingItem) inflate.findViewById(R.id.supply);
moreLi = (LSettingItem) inflate.findViewById(R.id.more);
installLi = (LSettingItem) inflate.findViewById(R.id.install);
}
}
使用依赖:
implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'com.leon:lsettingviewlibrary:1.3.0'
它们都是有点击事件的:
我简单实现了一个优惠券的点击事件:
public class DiscountsActivity extends AppCompatActivity implements View.OnClickListener {
private Button returnBt;
private TabLayout tabLayout;
private ViewPager disVp;
private String[] strings={"未使用(0)","已使用","已失效"};
private List list=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_discounts);
initView();
initData();
}
private void initData() {
list.add(new UnusedFragment());
list.add(new HavebeenusedFragment());
list.add(new EfficacyFragment());
DiscountsAdapter adapter = new DiscountsAdapter(getSupportFragmentManager(), list, strings);
disVp.setAdapter(adapter);
tabLayout.setupWithViewPager(disVp);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
}
private void initView() {
returnBt = (Button) findViewById(R.id.return_bt);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
disVp = (ViewPager) findViewById(R.id.dis_vp);
returnBt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DiscountsActivity.this.finish();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.return_bt:
break;
}
}
}
写到这里,项目基本完成:谢谢观赏
下载地址:https://download.csdn.net/my