五月份写了一篇底部弹出popwindow并且可以滑动的文章,当初只是一个小demo,现在应用到项目上了并且进行了优化,现在分享出来大家一起探讨进行优化。
数据请求为:Retrofut+rxjava,进行礼物布局的展示。
基本的思路为使用viewpage+grideView实现礼物的布局:
需要注意的地方为:
1、礼物数量以及礼物类型和图片为后台配置,因此需要联网请求服务器进行获得,而且可以进行左右滑动page进行展示下一屏礼物,需要动态的去创建page.
2、在选择礼物时有选中和取消两种状态,发送按钮应该随着选中状态的变化而改变。
3、在选中第一屏礼物时此时滑动至第二屏,再选中第二屏的某个礼物,需要把第一屏的那个礼物的选中状态取消(因为每个page是一个对象,做起来并不是那么简单)
不多说,直接上代码:
使用Retrofit+Rxjava进行简单的http数据请求,得到需要展示的giftLIst集合。
retrofit = RetrofitControler.getService();
Observable observable =retrofit.getGift("2.1.0", "ANDROID");
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
// 处理完成
Log.e("TAG", "onCompleted==>");
}
@Override
public void onError(Throwable e) {
// 处理异常
Log.e("TAG", "onError==>" + e);
}
@Override
public void onNext(ServerGiftBean s) {
// 处理响应结果
Log.e("TAG", "onNext==>" + s.data.size());
giftList = s.data;
}
});
进行礼物的Popwindow的初始化
void initGiftPopwindow(List giftList) {
View popView = ((LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.layout_pop_protrait_effectgift, null);
vp_gift_viewpager = (ViewPager) popView.findViewById(R.id.vp_gift_viewpager);
vp_gift_viewpager.setOnPageChangeListener(this);
llPointGroup = (LinearLayout) popView.findViewById(R.id.ll_guide_point_group);
mSelectPointView = (View) popView.findViewById(R.id.select_point);
btn_continue_click = (Button) popView.findViewById(R.id.btn_continue_click);
btn_continue_click.setOnClickListener(this);
btn_effect_gift_send = (Button) popView.findViewById(R.id.btn_effect_gift_send);
btn_effect_gift_send.setOnClickListener(this);
LinearLayout ll_gift_progress = (LinearLayout) popView.findViewById(R.id.ll_gift_progress);
gift_progress = (ProgressBar) popView.findViewById(R.id.gift_progress);
if(giftList==null || giftList.size() == 0){
ll_gift_progress.setVisibility(View.VISIBLE);
btn_effect_gift_send.setVisibility(View.GONE);
if (android.os.Build.VERSION.SDK_INT > 22) {//android 6.0替换clip的加载动画
final Drawable drawable = getApplicationContext().getResources().getDrawable(R.drawable.frame_loading2_v6);
gift_progress.setIndeterminateDrawable(drawable);
}
}
WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
int width = wm.getDefaultDisplay().getWidth();
int height = getResources().getDimensionPixelOffset(R.dimen.pop_gift_height);
effectGiftPopwindow = PopwindowUtils.getPopWindow(ctx, popView, width, height, R.color.half_transparent);
//popWindow消失监听方法
effectGiftPopwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
//改变图标状态
mc.onFinish();
}
});
}
根据获取的礼物的集合进行page的创建,根据产品的需求,每个page页面展示八个礼物,以此需要判断创建多个个page。
private void showGifViewWindow(List giftList) {
if (effectGiftPopwindow == null) {
initGiftPopwindow(giftList);
if (giftList != null && giftList.size() != 0) {
for (int i = 0; i < (giftList.size() - 1) / 8 + 1; i++) {
initGrideView(i);
}
if ((giftList.size() - 1) / 8 > 0) {
initDots((giftList.size() - 1) / 8 + 1);
}
GiftPageAdapter giftPageAdapter = new GiftPageAdapter();
vp_gift_viewpager.setAdapter(giftPageAdapter);
}
}
effectGiftPopwindow.showAtLocation(btn_gift, Gravity.BOTTOM, 0, 0);
resetState(mGiftId, mGiftName);
}
进行page创建时我会把创建的每个page对象存放在一个集合中,此目的就是为了解决上面第三点提到的问题,解决此问题的代码为上图中的增强for循环,判断此时我点击的礼物属于哪个page,其他的page进行adapter的重置。
private void initGrideView(int i) {
CustomGrideView mGifGrideView = new CustomGrideView(ctx, giftList, i);
grideList.add(mGifGrideView);
mGifGrideView.setOnGiftSelectCallBack(new CustomGrideView.EffectGiftCallBack() {
@Override
public void effectGiftId(String giftId, String giftType, String giftName, int type) {
Log.e("effectGiftId", "giftId===>" + giftId + "giftType===>" + giftType + "giftName====>" + giftName);
mGiftId = giftId;
mGiftType = giftType;
mGiftName = giftName;
for (CustomGrideView mGride : grideList) {
if (mGride != null && mGride.getType() != type) {
mGride.clearAdapter();
}
}
resetState(giftId,giftName);
mc.onFinish();
}
});
imageViewList.add(mGifGrideView.getViews());
}
在每个page页面的礼物展示时,我需要给每个adapter传递当前页面的数据,但是我目前的数据时全部礼物的数据,因此我需要进行数据的拆分,把当前页面的八条礼物数据拿出来然后再给adapter。
private List getNewGiftList(int type){
int maxLength=0;
if(type*8+8>gift.size()){
maxLength= gift.size();
}else {
maxLength=type*8+8;
}
for(int i=type*8;i
当进行礼物点击时还需要判断是否是选中状态下还是未选中状态下的点击,如为未选中状态下的点击时需要置为选中状态,如为选中状态下的点击时则需要置为未选中状态。
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
if(selectId != position){
GiftListLayoutBean giftBean = (GiftListLayoutBean)parent.getItemAtPosition(position);
onGiftSelectCallBack.effectGiftId(giftBean.giftId,giftBean.giftType,giftBean.giftName,type);
selectId = position;
grideViewAdapter.setIndex(selectId);
grideViewAdapter.notifyDataSetChanged();
}else{
onGiftSelectCallBack.effectGiftId("","","",type);
selectId = -1;
grideViewAdapter.setIndex(selectId);
grideViewAdapter.notifyDataSetChanged();
}
}
大致的代码就是这样的,没什么技术难点,重要的就是逻辑的判断,有什么地方写的不好的请多多指教。
源码地址为:https://github.com/swinner/LivetelecastGiftDemo