国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義SeekBar實現視頻播放進度條

2019-12-12 03:13:09
字體:
來源:轉載
供稿:網友

首先來看一下效果圖,如下所示:

其中進度條如下:

接下來說一說我的思路,上面的進度拖動條有自定義的Thumb,在Thumb正上方有一個PopupWindow窗口,窗口里面顯示當前的播放時間。在SeekBar右邊有一個文本框顯示當前播放時間/總時間。

step1、先來看一看PopupWindow的布局文件,seek_popu.xml,效果如下圖所示:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:background="@drawable/seek_dialog_bg" >  <!-- 展現當前播放進度時間的文本框-->  <TextView   android:id="@+id/dialogSeekTime"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_marginLeft="10dip"   android:layout_marginTop="12dip"   android:text="@string/unknow_seek_time"   android:textColor="@color/black"   android:textSize="12sp" /> </RelativeLayout> 

step2、自定義一個SeekBar

import com.canplay.video.R;  import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.PopupWindow; import android.widget.SeekBar; import android.widget.TextView;  /**  * 自定義進度拖動條控件  */ public class MySeekBar extends SeekBar {  /**   * 定義一個展現時間的PopupWindow   */  private PopupWindow mPopupWindow;    private View mView;  /**   * 顯示時間的TextView   */  private TextView dialogSeekTime;  /**   * 用來表示該組件在整個屏幕內的絕對坐標,其中 mPosition[0] 代表X坐標,mPosition[1] 代表Y坐標。   */  private int[] mPosition;  /**   * SeekBar上的Thumb的寬度,即那個托動的小黃點的寬度   */  private final int mThumbWidth = 25;   public MySeekBar(Context context) {   this(context, null);  }   public MySeekBar(Context context, AttributeSet attrs) {   super(context, attrs);   mView = LayoutInflater.from(context).inflate(R.layout.seek_popu, null);   dialogSeekTime = (TextView) mView.findViewById(R.id.dialogSeekTime);   mPopupWindow = new PopupWindow(mView, mView.getWidth(), mView.getHeight(), true);   mPosition = new int[2];  }   /**   * 獲取控件的寬度   *   * @param v   * @return 控件的寬度   */  private int getViewWidth(View v) {   int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);   int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);   v.measure(w, h);   return v.getMeasuredWidth();  }   /**   * 獲取控件的高度   *   * @param v   * @return 控件的高度   */  private int getViewHeight(View v) {   int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);   int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);   v.measure(w, h);   return v.getMeasuredHeight();  }   /**   * 隱藏進度拖動條的PopupWindow   */  public void hideSeekDialog() {   if (mPopupWindow != null && mPopupWindow.isShowing()) {    mPopupWindow.dismiss();   }  }   /**   * 顯示進度拖動條的PopupWindow   *   * @param str   *     時間值   */  public void showSeekDialog(String str) {   dialogSeekTime.setText(str);   int progress = this.getProgress();   // 計算每個進度值所占的寬度   int thumb_x = (int) (progress * (1.0f * (this.getWidth() - 22) / this.getMax())); //22是兩邊的空白部分寬度   // 更新后的PopupWindow的Y坐標   int middle = this.getHeight() / 2 + 120;   if (mPopupWindow != null) {    try {     /*      * 獲取在整個屏幕內的絕對坐標,注意這個值是要從屏幕頂端算起,也就是包括了通知欄的高度。      * 其中 mPosition[0] 代表X坐標,mPosition[1]代表Y坐標。      */     this.getLocationOnScreen(mPosition);     // 相對某個控件的位置(正左下方),在X、Y方向各有偏移     mPopupWindow.showAsDropDown(this, (int) mPosition[0], mPosition[1]);     /*      * 更新后的PopupWindow的X坐標      * 首先要把當前坐標值減去PopWindow的寬度的一半,再加上Thumb的寬度一半。      * 這樣才能使PopWindow的中心點和Thumb的中心點的X坐標相等      */     int x = thumb_x + mPosition[0] - getViewWidth(mView) / 2 + mThumbWidth / 2;     // 更新popup窗口的位置     mPopupWindow.update(x, middle, getViewWidth(mView), getViewHeight(mView));    } catch (Exception e) {    }   }  } } 

step3、將自定義的拖動條加入到布局文件中,下面是部分代碼

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:background="@android:color/black" > ...... <!-- 進度拖動條 -->   <RelativeLayout    android:id="@+id/seek_bar_container"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:layout_above="@id/control_btn_container"    android:background="@drawable/seek_bg" >     <com.canplay.video.view.MySeekBar     android:id="@+id/seek_progress"     android:layout_width="600dip"     android:layout_height="wrap_content"     android:layout_centerInParent="true" />     <TextView     android:id="@+id/currentTime"     style="@style/seekTime"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_centerVertical="true"     android:layout_toRightOf="@id/seek_progress"     android:paddingLeft="20dip"     android:text="@string/unknow_time" />   </RelativeLayout> ............... </RelativeLayout> 

step4、在主文件中對拖動條進行托動監聽

mSeekBar = (MySeekBar) findViewById(R.id.seek_progress); mSeekBar.setOnSeekBarChangeListener(mSeekBarListener); /**   * 進度拖動條監聽器   */  private OnSeekBarChangeListener mSeekBarListener = new OnSeekBarChangeListener() {   // 通知進度已經被修改   public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {    if (isTouchSeeked) {     mSeekBar.showSeekDialog(makeTimeString(progress));//動態展示當前播放時間    } else {     mSeekBar.hideSeekDialog();    }   }    // 通知用戶已經開始一個觸摸拖動手勢   public void onStartTrackingTouch(SeekBar seekBar) {    showControlView(3600000);    isTouchSeeked = true;   }    // 通知用戶觸摸手勢已經結束   public void onStopTrackingTouch(SeekBar seekBar) {    Message msg = Message.obtain();    msg.what = PROGRESS_SEEKTO;    msg.arg1 = seekBar.getProgress();    mHandler.removeMessages(PROGRESS_SEEKTO);    mHandler.sendMessageAtTime(msg, 1000);// 1秒之后開始發送更新進度的消息    isTouchSeeked = false;    showControlView(sDefaultTimeout);   }  }; 

其中將進度值轉換為時間的方法makeTimeString(int secs)如下所示:

/**   * 格式化的Builder   */  private StringBuilder sFormatBuilder = new StringBuilder();  /**   * 格式化的Formatter   */  private Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault());  /**   * 格式化的相關屬性   */  private final Object[] sTimeArgs = new Object[3];   /**   * 轉換進度值為時間   *   * @param secs   * @return   */  private String makeTimeString(int secs) {   /**    * %[argument_index$][flags][width]conversion 可選的    * argument_index 是一個十進制整數,用于表明參數在參數列表中的位置。第一個參數由 "1$"    * 引用,第二個參數由 "2$" 引用,依此類推。 可選 flags    * 是修改輸出格式的字符集。有效標志集取決于轉換類型。 可選 width    * 是一個非負十進制整數,表明要向輸出中寫入的最少字符數。 可選 precision    * 是一個非負十進制整數,通常用來限制字符數。特定行為取決于轉換類型。 所需 conversion    * 是一個表明應該如何格式化參數的字符。給定參數的有效轉換集取決于參數的數據類型。    */   String durationformat = getString(R.string.durationformat);// <xliff:g         // id="format">%1$02d:%2$02d:%3$02d</xliff:g>   sFormatBuilder.setLength(0);   secs = secs / 1000;   Object[] timeArgs = sTimeArgs;   timeArgs[0] = secs / 3600; // 秒   timeArgs[1] = (secs % 3600) / 60; // 分   timeArgs[2] = (secs % 3600 % 60) % 60; // 時   return sFormatter.format(durationformat, timeArgs).toString().trim();  } 

當然,這里只是簡單的介紹了下自定義進度條,而該進度條的樣式都沒有展現出來,樣式讀者可以自己定義。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 绥化市| 吉木萨尔县| 本溪市| 义乌市| 望江县| 洱源县| 集安市| 宝鸡市| 沛县| 龙岩市| 普格县| 凤翔县| 宁陕县| 安塞县| 楚雄市| 大渡口区| 江川县| 贡嘎县| 什邡市| 克拉玛依市| 沧州市| 阿坝县| 仪征市| 铜梁县| 海伦市| 长海县| 五河县| 石阡县| 凤庆县| 梓潼县| 濉溪县| 兰坪| 仪陇县| 句容市| 桃源县| 荥经县| 宽甸| 张家口市| 保德县| 根河市| 中阳县|