标签:
需求:类似网易新闻客户端,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() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub mPager.getGestureDetector().onTouchEvent(event); // TODO Auto-generated method stub final 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 stub mList = new ArrayList<View>(); for(int i = 0; i<size;i++){ View item = LayoutInflater.from(context).inflate(R.layout.ads_item ,null); mList.add(item); } } @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } // 来判断显示的是否是同一张图片,这里我们将两个参数相比较返回即可 @Override public boolean isViewFromObject(View arg0, Object arg1) { // TODO Auto-generated method stub return arg0 == arg1; } // PagerAdapter只缓存三张要显示的图片,如果滑动的图片超出了缓存的范围,就会调用这个方法,将图片销毁 @Override public 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中,然后作为返回值返回即可 @Override public Object instantiateItem(ViewGroup container, int position) { // TODO Auto-generated method stub View 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{//点击广告栏的监听 @Override public void setOnSimpleClickListenr(int position) { // TODO Auto-generated method stub if(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); } } }
//添加广告位的异步任务的部分代码 @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.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(); } } }
标签:
原文地址:http://www.cnblogs.com/lucky-star-star/p/4610321.html