如何單手?jǐn)]一個(gè)Banner活動(dòng)圖

最近看到公司項(xiàng)目用的是一個(gè)webView實(shí)現(xiàn)的Banner寨昙,個(gè)人覺(jué)得用戶體驗(yàn)不怎么好,第一:用戶點(diǎn)擊banner圖還可以輕微的上下滑動(dòng)(難適配的原因)老翘;第二:用戶息屏之后再打開(kāi)芹啥,webView會(huì)閃一下,這個(gè)原因還沒(méi)找到铺峭,知道的同學(xué)可以指教一下墓怀。這肯定不能忍,對(duì)不對(duì)卫键!網(wǎng)上也有很多這方面的文章了吧傀履,但那究竟是別人的,自己寫(xiě)的應(yīng)該會(huì)更爽一些吧莉炉。

首先钓账,分析下需求:

  • 幾張圖片過(guò)一段時(shí)間就切換一次;
  • 當(dāng)觸摸圖片絮宁,圖片暫停切換梆暮;
大概思路大家都想到用ViewPager去實(shí)現(xiàn) --> ok,需求分析完畢绍昂。下面先編寫(xiě)XML:

<pre>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
tools:context="test.nicely.com.application.MainActivity">

   <android.support.v4.view.ViewPager
     android:id="@+id/view_pager"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
   </android.support.v4.view.ViewPager>
  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="#55000000"
    android:padding="5dp">
       <TextView
         android:id="@+id/tv_img_desc"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_centerHorizontal="true"
         android:text="banner"
         android:textColor="#ffffff"
         android:textSize="16sp"/>
  //   小圓點(diǎn)的容器,用來(lái)動(dòng)態(tài)添加
     <LinearLayout
        android:layout_centerVertical="true"
        android:id="@+id/dot_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="8dp"
        android:orientation="horizontal">
     </LinearLayout>
  </RelativeLayout>

</RelativeLayout>
</pre>


直接貼代碼吧 ,畢竟Talk is cheap ,接下看MainActivity類(lèi)的代碼邏輯處理:
public class MainActivity extends AppCompatActivity  implements ViewPager.OnPageChangeListener,
                                                            View.OnTouchListener {
  private String[] arrUrl = {AppConstant.baseUrl + "teacher_1.png",
                             AppConstant.baseUrl + "teacher_2.png",
                             AppConstant.baseUrl + "teacher_3.png"};
  // mock banner Title
  private int[]    resTxt = {R.string.title_1, R.string.title_2, R.string.title_3};
  private ViewPager      mViewPager;
  private LinearLayout   mDot_container;
  private MyPagerAdapter mAdapter;
  private TextView       mTvImgDesc;
  private int            mPrePosition;
  //private AutoCycleTask  mAutoCycleTask;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
        // 設(shè)置全透明的狀態(tài)欄
      CommonUtils.setTransparentStatus(this);
      initView();
      performDot();
      performViewPager();
  
  }
  
  private void initView() {
      mViewPager = (ViewPager) findViewById(R.id.view_pager);
      mDot_container = (LinearLayout) findViewById(R.id.dot_container);
      mTvImgDesc = (TextView) findViewById(R.id.tv_img_desc);
  }
  
  private void performDot() {
      for (int i = 0; i < resTxt.length; i++) {
          View dotView = new View(this);
          dotView.setBackgroundResource(R.drawable.dot);
          LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(15, 15);
          // 第一個(gè)原點(diǎn)不設(shè)置左邊距
          if (i != 0) {
              params.leftMargin = 15;
          }
          dotView.setEnabled(false);
          dotView.setLayoutParams(params);
          mDot_container.addView(dotView);
      }
  }
  
  private void performViewPager() {
      if (mAdapter == null) {
          mAdapter = new MyPagerAdapter(this, arrUrl);
      }
      mViewPager.setAdapter(mAdapter);
      mViewPager.addOnPageChangeListener(this);
      mViewPager.setOnTouchListener(this);
      // Integer.MAX_VALUE / 2 有可能是任何item的位置 - 余數(shù)則讓他和集合的pos=0的位置吻合
      int item = Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2 % resTxt.length);
      mViewPager.setCurrentItem(item);// 設(shè)置初始位置
      // 將第一個(gè)圓點(diǎn)設(shè)置選中的顏色
      mDot_container.getChildAt(mPrePosition).setEnabled(true);
      mTvImgDesc.setText(resTxt[mPrePosition]);
        // 實(shí)現(xiàn) 自動(dòng)切換
      autoCycle();
  }
  
  private void autoCycle() {
      if (mAutoCycleTask == null) {
          mAutoCycleTask = new AutoCycleTask();
      }
      mAutoCycleTask.start();
  }
  
  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
      Log.d("nicely","position===" + position + "positionOffset===" + positionOffset + "positionOffsetPixels===" + positionOffsetPixels);

 }
 
 @Override
 public void onPageSelected(int position) {
     int newPos = position % mDot_container.getChildCount();
     mDot_container.getChildAt(mPrePosition).setEnabled(false);
     mDot_container.getChildAt(newPos).setEnabled(true);
     mTvImgDesc.setText(resTxt[newPos]);
     mPrePosition = newPos;
 }
 
 @Override
 public void onPageScrollStateChanged(int state) {
 }
}
上面的邏輯也比較簡(jiǎn)單,簡(jiǎn)單梳理一下: 動(dòng)態(tài)添加小圓點(diǎn)到線性布局當(dāng)中;監(jiān)聽(tīng)Viewpager選中的item動(dòng)態(tài)切換小圓點(diǎn)的選中位置;再把PagerAdapter的subclass代碼貼上來(lái):
/*
 *  @項(xiàng)目名:  Application 
 *  @包名:    test.nicely.com.application
 *  @文件名:   MyPagerAdapter
 *  @創(chuàng)建者:   lz
 *  @創(chuàng)建時(shí)間:  2017/1
 *  @描述:    TODO
 */
public class MyPagerAdapter extends PagerAdapter {
  private static final String TAG = "MyPagerAdapter";
  private Context mContext;
  private String[] mArrUrl;
  
  public MyPagerAdapter(Context context, String[] arrUrl) {
      mContext = context;
      mArrUrl = arrUrl;
  }
  
  @Override
  public int getCount() {
      // return arrUrl.lenth;
    // 循環(huán)用
      return Integer.MAX_VALUE;
  }
  
  @Override
  public boolean isViewFromObject(View view, Object object) {
      return view == object;
  }
  
  @Override
  public Object instantiateItem(ViewGroup container, int position) {
      // position此時(shí)的總大小是Integer.MAX_VALUE,需要轉(zhuǎn)換(position本來(lái)就跟自然數(shù)差1了)
      // 循環(huán)用
      position = position % mArrUrl.length;
      ImageView imageView = new ImageView(mContext);
      imageView.setScaleType(ImageView.ScaleType.FIT_XY);
    // 使用picasso加載圖片
      Picasso.with(mContext).load(mArrUrl[position]).error(R.mipmap.error).into(imageView);
      container.addView(imageView);
      return imageView;
  }
  
  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
  
      container.removeView((View) object);
  }
}
到此為止,就差我們想要的循環(huán)沒(méi)有實(shí)現(xiàn)了.這里有些同學(xué)可能會(huì)在這里踩坑----> 高能預(yù)警!!!有些同學(xué)在這個(gè)方法里instantiateItem使用的是從外邊傳的View進(jìn)來(lái),這時(shí)候你一切換view ,就會(huì)報(bào)下邊這個(gè)錯(cuò)誤:

This view has a parent...

可能是大家對(duì)Viewpager不熟悉,加上自己的想當(dāng)然所導(dǎo)致的哈,接下來(lái)我們就要實(shí)現(xiàn)動(dòng)態(tài)切換了:實(shí)現(xiàn)這個(gè)定時(shí)器功能.

android中有許多方式,什么Timer ,alarmmanager,Handler等等.

我這里選擇是Handler,ok,老套路,直接貼實(shí)現(xiàn)定時(shí)器邏輯代碼(AutoCycleTask類(lèi)是MainActivity的內(nèi)部類(lèi)),自定義了一個(gè)start()和stop()方法:
class AutoCycleTask  extends Handler implements Runnable {
    @Override
    public void run() {
        // 設(shè)置輪播下一圖
        int currentItem = mViewPager.getCurrentItem();
        mViewPager.setCurrentItem(++currentItem);
        postDelayed(this, 2000);
    }

    public void start() {
        postDelayed(this, 2000);
    }

    public void stop() {
        removeCallbacks(this);
    }
}
接下來(lái)在界面銷(xiāo)毀時(shí),將handler消息隊(duì)列中的消息移除:
@Override
protected void onDestroy() {
    super.onDestroy();
    mAutoCycleTask.removeCallbacksAndMessages(null);
    mAutoCycleTask = null;
}
最后還差一個(gè)需求點(diǎn)沒(méi)完成
  • 當(dāng)觸摸圖片惕蹄,圖片暫停切換.
這不就監(jiān)聽(tīng)Viewpager的觸摸事件就可以搞定了:
 @Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mAutoCycleTask.stop();
             break;
        case MotionEvent.ACTION_MOVE:
            mAutoCycleTask.stop();
            break;
        case MotionEvent.ACTION_UP:
            mAutoCycleTask.start();
            break;
    }
    return false;
}

貼上截圖(簡(jiǎn)書(shū)暫時(shí)不會(huì)搞GIF圖 [尷尬]):

Screenshot_20170119-200739.png

Done! 由于知識(shí)水平有限,歡迎各位同學(xué)指出"辣眼睛"之處,哈哈, 最后祝大家周末愉快!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子卖陵,更是在濱河造成了極大的恐慌遭顶,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泪蔫,死亡現(xiàn)場(chǎng)離奇詭異棒旗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)撩荣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)铣揉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人餐曹,你說(shuō)我怎么就攤上這事逛拱。” “怎么了台猴?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵朽合,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我饱狂,道長(zhǎng)曹步,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任休讳,我火速辦了婚禮讲婚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俊柔。我一直安慰自己筹麸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布雏婶。 她就那樣靜靜地躺著竹捉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尚骄。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天侵续,我揣著相機(jī)與錄音倔丈,去河邊找鬼。 笑死状蜗,一個(gè)胖子當(dāng)著我的面吹牛需五,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轧坎,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宏邮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蜜氨,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤械筛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后飒炎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體埋哟,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年郎汪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赤赊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡煞赢,死狀恐怖抛计,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情照筑,我是刑警寧澤吹截,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站朦肘,受9級(jí)特大地震影響饭弓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜媒抠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一弟断、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧趴生,春花似錦阀趴、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至浸踩,卻和暖如春叔汁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背检碗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工据块, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人折剃。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓另假,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親怕犁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子边篮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容