安卓 广告位
需求:類似網易新聞客戶端,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();}}}?
轉載于:https://www.cnblogs.com/lucky-star-star/p/4610321.html
總結
- 上一篇: Facebook应用Moments使用C
- 下一篇: Swift中的区间运算符和半开区间运算符