需求:类似网易新闻客户端,listview头部要显示广告位,广告位数量动态从后台获取,并且不一定一直有广告位
问题:listview下拉刷新与广告位touch事件的冲突解决,广告位的左滑右滑事件与整个fragment的左右切换事件冲突解决,广告位的数量动态获取,作为listview的header显示解决
实际做的过程中碰到的问题:
1、广告位的控件是继承自PagerAdapter,许多应用的广告位的显示是基于首先知道广告的数量的,这样在new adapter的时候,就可以分配多少数量,这样在adapter就可以直接加载显示图片。但是我们的应用是直接从后台拉取图片数量,所以我在new adapter之前是不知道图片的数量的。我尝试吧这个拉取广告的异步任务放在刚进主页的时候进行,进广告这页的时候直接加载。但是会出现这样的问题,如果没网的话,主页是拉取不到广告的,这样在进广告主页的时候,会出现listview的头部是空白的情况,然后我在listview进行addheaderView()的时候,进行了一下判断,如果拉取的广告位空的话,就不加载头部。这样虽然头部空白的问题解决了,但是当用户此时再次切换到有网的状态是,进行下拉刷新,应该是执行拉取广告的异步任务的,重新刷出来广告位。结果我发现,拉取到了广告,但是header没有被add进去呀,你不能在异步任务执行完,在add一遍,因为add必须放在listview在set Adapter之前完成。所以怎么办呢?
1.1进行的判断不应该限制listview添加header,而是隐藏header,并且隐藏的还不能是头部的根布局,必须是你显示广告图片的那个控件,可以参考这个http://blog.csdn.net/ethan_xue/article/details/9852209
1.2 可是我事先不知道广告的数量呐,这种情况可以再拉取广告图片的异步任务的post函数中,拿到广告的图片数量以后,再让广告设置一遍adapter就可以了,以下四行代码
adsAdapter = new AdvAdapter(HomeFrag.recommendAdsList.size());
mPager.setAdapter(adsAdapter);
adsAdapter.notifyDataSetChanged();
findmoreAdapter.notifyDataSetChanged();
这样原来被隐藏的广告位下拉刷新执行完异步之后,广告位就又出来了。
1.3 adsAdapter.notifyDataSetChanged();这句话的执行,如果不修改一下pageradapter是不行的,参考这个http://blog.csdn.net/gzsword/article/details/7284288
所以需要再adsadapter的里面添加几行代码:
@Override public int getItemPosition(Object object) { return POSITION_NONE; }
综上,附上完整的代码:
/** 添加HeadView(广告控件) **/private void addHeadView(LayoutInflater inflater) {mHeadView = (View) inflater.inflate(R.layout.fragment_head_view, null);mPager = (MyViewPager) mHeadView.findViewById(R.id.fragment_view_pager);//显示广告图片的 viewpager adsAdapter = new AdvAdapter(HomeFrag.recommendAdsList.size());//这个list是刚进主页的拉取广告数量的数组,不是持久的数据 mPager.setAdapter(adsAdapter);mPager.setOnSimpleClickListener(new AdsImageViewOnClickLostener());mPager.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stub mPager.getGestureDetector().onTouchEvent(event);// TODO Auto-generated method stubfinal float x = event.getRawX();final float y = event.getRawY();switch (event.getAction()) { case MotionEvent.ACTION_DOWN: xDistance = yDistance = 0f;mLastMotionX = x;mLastMotionY = y;case MotionEvent.ACTION_MOVE: final float xDiff = Math.abs(x - mLastMotionX);final float yDiff = Math.abs(y - mLastMotionY);xDistance += xDiff;yDistance += yDiff;float dx = xDistance - yDistance;/** 左右滑动避免和下拉刷新冲突 **/if (xDistance > yDistance || Math.abs(xDistance - yDistance) < 0.00001f) {mIsBeingDragged = true;mLastMotionX = x;mLastMotionY = y;((ViewParent) v.getParent()).requestDisallowInterceptTouchEvent(true);} else {mIsBeingDragged = false;((ViewParent) v.getParent()).requestDisallowInterceptTouchEvent(false);}break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_CANCEL:if(mIsBeingDragged) {((ViewParent) v.getParent()).requestDisallowInterceptTouchEvent(false);}break;default: break; } return false; }});if(HomeFrag.recommendAdsList.size()!=0){myListView.setTag(mPager);myListView.addHeaderView(mHeadView,null,false);adsAdapter.notifyDataSetChanged();}else{//暂时先隐藏headview,广告从无到有刷新出来再可见 myListView.setTag(mPager);myListView.addHeaderView(mHeadView,null,false);mPager.setVisibility(View.GONE);adsAdapter.notifyDataSetChanged();}}
/** 广告控件适配器 **/public class AdvAdapter extends PagerAdapter{private List<View> mList ;public AdvAdapter(int size) {// TODO Auto-generated constructor stubmList = new ArrayList<View>();for(int i = 0; i<size;i++){View item = LayoutInflater.from(context).inflate(R.layout.ads_item ,null);mList.add(item);}}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn mList.size();}// 来判断显示的是否是同一张图片,这里我们将两个参数相比较返回即可 @Overridepublic boolean isViewFromObject(View arg0, Object arg1) {// TODO Auto-generated method stubreturn arg0 == arg1; }// PagerAdapter只缓存三张要显示的图片,如果滑动的图片超出了缓存的范围,就会调用这个方法,将图片销毁 @Overridepublic void destroyItem(ViewGroup container, int position, Object object) {// TODO Auto-generated method stub ((ViewPager) container).removeView(mList.get(position));//mPager.removeViewCache(position); }@Override public void finishUpdate(View arg0) {} @Override public void restoreState(android.os.Parcelable state, ClassLoader loader) { }; @Override public Parcelable saveState() { return null; } @Override public void startUpdate(View arg0) {} // 当要显示的图片可以进行缓存的时候,会调用这个方法进行显示图片的初始化,我们将要显示的ImageView加入到ViewGroup中,然后作为返回值返回即可 @Overridepublic Object instantiateItem(ViewGroup container, int position) {// TODO Auto-generated method stubView view = mList.get(position);ImageView image = ((ImageView) view.findViewById(R.id.image));TextView text_view = (TextView) view.findViewById(R.id.ads_tv);Bitmap bitmap = null;if(HomeFrag.recommendAdsList.size()!=0){bitmap = BitmapFactory.decodeFile(HomeFrag.recommendAdsList.get(position).picPath);image.setImageBitmap(bitmap);if(HomeFrag.recommendAdsList.get(position).adsTitle!=null&&HomeFrag.recommendAdsList.get(position).adsTitle.equals("")){text_view.setVisibility(View.INVISIBLE);}else{text_view.setVisibility(View.VISIBLE);text_view.setText(HomeFrag.recommendAdsList.get(position).adsTitle);}}container.removeView(mList.get(position));container.addView(mList.get(position));// adapter.notifyDataSetChanged();return mList.get(position);}@Override public int getItemPosition(Object object) {//加上这个,adsAdapter.notifyDataSetChanged()才可以刷新return POSITION_NONE; } }public class AdsImageViewOnClickLostener implements onSimpleClickListener{//点击广告栏的监听 @Overridepublic void setOnSimpleClickListenr(int position) {// TODO Auto-generated method stubif(HomeFrag.recommendAdsList.get(position).adsType.equals("1")){//跳转到签到界面,加载网页//GPUtils.toast(context, recommendAdsList.get(position).adsType);Intent intent = new Intent();intent.putExtra("source", "ads");intent.putExtra("ads_url", HomeFrag.recommendAdsList.get(position).adsUrl);intent.setClass(getActivity(),SigninActivity.class);getActivity().startActivity(intent);}else {Intent intent = new Intent(context,MyFavouriteDetailsActivity.class);Bundle bundle = new Bundle();bundle.putInt("position", position);bundle.putString("label", HomeFrag.recommendAdsList.get(position).articleType);if(HomeFrag.recommendAdsList.get(position).adsType.equals("2")){//官方发布的文章bundle.putString("source", "AdsArticleHjz");}else if(HomeFrag.recommendAdsList.get(position).adsType.equals("3")){//用户发布的文章bundle.putString("source", "AdsArticleUser");} intent.putExtras(bundle);startActivity(intent);}}}
//添加广告位的异步任务的部分代码 @Overrideprotected void onPostExecute(String result) {// TODO Auto-generated method stubsuper.onPostExecute(result);if (result != null) {if (result.equals("success")) {HomeFrag.recommendAdsList.clear();for (int i = 0; i < recommendAdsListTemp.size(); i++) {HomeFrag.recommendAdsList.add(recommendAdsListTemp.get(i));}if(HomeFrag.recommendAdsList.size()!=0){mPager.setVisibility(View.VISIBLE);}adsAdapter = new AdvAdapter(HomeFrag.recommendAdsList.size());//重新设置一下适配器,更新广告位 mPager.setAdapter(adsAdapter);//addHeadView(LayoutInflater.from(context));//这个是执行不了的 adsAdapter.notifyDataSetChanged();findmoreAdapter.notifyDataSetChanged();}}}