最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義SeekBar實(shí)現(xiàn)視頻播放進(jìn)度條

 更新時(shí)間:2020年03月25日 14:19:54   作者:歐陽(yáng)鵬  
這篇文章主要為大家詳細(xì)介紹了Android自定義SeekBar實(shí)現(xiàn)視頻播放進(jìn)度條的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android實(shí)現(xiàn)視頻播放進(jìn)度條的具體代碼,供大家參考,具體內(nèi)容如下

首先來(lái)看一下效果圖,如下所示:

其中進(jìn)度條如下:

接下來(lái)說(shuō)一說(shuō)我的思路,上面的進(jìn)度拖動(dòng)條有自定義的Thumb,在Thumb正上方有一個(gè)PopupWindow窗口,窗口里面顯示當(dāng)前的播放時(shí)間。在SeekBar右邊有一個(gè)文本框顯示當(dāng)前播放時(shí)間/總時(shí)間。

step1、先來(lái)看一看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" > 
 <!-- 展現(xiàn)當(dāng)前播放進(jìn)度時(shí)間的文本框--> 
 <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、自定義一個(gè)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; 
 
/** 
 * 自定義進(jìn)度拖動(dòng)條控件 
 */ 
public class MySeekBar extends SeekBar { 
 /** 
 * 定義一個(gè)展現(xiàn)時(shí)間的PopupWindow 
 */ 
 private PopupWindow mPopupWindow; 
 
 private View mView; 
 /** 
 * 顯示時(shí)間的TextView 
 */ 
 private TextView dialogSeekTime; 
 /** 
 * 用來(lái)表示該組件在整個(gè)屏幕內(nèi)的絕對(duì)坐標(biāo),其中 mPosition[0] 代表X坐標(biāo),mPosition[1] 代表Y坐標(biāo)。 
 */ 
 private int[] mPosition; 
 /** 
 * SeekBar上的Thumb的寬度,即那個(gè)托動(dòng)的小黃點(diǎn)的寬度 
 */ 
 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(); 
 } 
 
 /** 
 * 隱藏進(jìn)度拖動(dòng)條的PopupWindow 
 */ 
 public void hideSeekDialog() { 
 if (mPopupWindow != null && mPopupWindow.isShowing()) { 
  mPopupWindow.dismiss(); 
 } 
 } 
 
 /** 
 * 顯示進(jìn)度拖動(dòng)條的PopupWindow 
 * 
 * @param str 
 *   時(shí)間值 
 */ 
 public void showSeekDialog(String str) { 
 dialogSeekTime.setText(str); 
 int progress = this.getProgress(); 
 // 計(jì)算每個(gè)進(jìn)度值所占的寬度 
 int thumb_x = (int) (progress * (1.0f * (this.getWidth() - 22) / this.getMax())); //22是兩邊的空白部分寬度 
 // 更新后的PopupWindow的Y坐標(biāo) 
 int middle = this.getHeight() / 2 + 120; 
 if (mPopupWindow != null) { 
  try { 
  /* 
   * 獲取在整個(gè)屏幕內(nèi)的絕對(duì)坐標(biāo),注意這個(gè)值是要從屏幕頂端算起,也就是包括了通知欄的高度。 
   * 其中 mPosition[0] 代表X坐標(biāo),mPosition[1]代表Y坐標(biāo)。 
   */ 
  this.getLocationOnScreen(mPosition); 
  // 相對(duì)某個(gè)控件的位置(正左下方),在X、Y方向各有偏移 
  mPopupWindow.showAsDropDown(this, (int) mPosition[0], mPosition[1]); 
  /* 
   * 更新后的PopupWindow的X坐標(biāo) 
   * 首先要把當(dāng)前坐標(biāo)值減去PopWindow的寬度的一半,再加上Thumb的寬度一半。 
   * 這樣才能使PopWindow的中心點(diǎn)和Thumb的中心點(diǎn)的X坐標(biāo)相等 
   */ 
  int x = thumb_x + mPosition[0] - getViewWidth(mView) / 2 + mThumbWidth / 2; 
  // 更新popup窗口的位置 
  mPopupWindow.update(x, middle, getViewWidth(mView), getViewHeight(mView)); 
  } catch (Exception e) { 
  } 
 } 
 } 
} 

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

 <?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" > 
...... 
<!-- 進(jìn)度拖動(dòng)條 --> 
 <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、在主文件中對(duì)拖動(dòng)條進(jìn)行托動(dòng)監(jiān)聽(tīng)

mSeekBar = (MySeekBar) findViewById(R.id.seek_progress); 
mSeekBar.setOnSeekBarChangeListener(mSeekBarListener); 
/** 
 * 進(jìn)度拖動(dòng)條監(jiān)聽(tīng)器 
 */ 
 private OnSeekBarChangeListener mSeekBarListener = new OnSeekBarChangeListener() { 
 // 通知進(jìn)度已經(jīng)被修改 
 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
  if (isTouchSeeked) { 
  mSeekBar.showSeekDialog(makeTimeString(progress));//動(dòng)態(tài)展示當(dāng)前播放時(shí)間 
  } else { 
  mSeekBar.hideSeekDialog(); 
  } 
 } 
 
 // 通知用戶已經(jīng)開(kāi)始一個(gè)觸摸拖動(dòng)手勢(shì) 
 public void onStartTrackingTouch(SeekBar seekBar) { 
  showControlView(3600000); 
  isTouchSeeked = true; 
 } 
 
 // 通知用戶觸摸手勢(shì)已經(jīng)結(jié)束 
 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秒之后開(kāi)始發(fā)送更新進(jìn)度的消息 
  isTouchSeeked = false; 
  showControlView(sDefaultTimeout); 
 } 
 }; 

其中將進(jìn)度值轉(zhuǎn)換為時(shí)間的方法makeTimeString(int secs)如下所示:

/** 
 * 格式化的Builder 
 */ 
 private StringBuilder sFormatBuilder = new StringBuilder(); 
 /** 
 * 格式化的Formatter 
 */ 
 private Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault()); 
 /** 
 * 格式化的相關(guān)屬性 
 */ 
 private final Object[] sTimeArgs = new Object[3]; 
 
 /** 
 * 轉(zhuǎn)換進(jìn)度值為時(shí)間 
 * 
 * @param secs 
 * @return 
 */ 
 private String makeTimeString(int secs) { 
 /** 
  * %[argument_index$][flags][width]conversion 可選的 
  * argument_index 是一個(gè)十進(jìn)制整數(shù),用于表明參數(shù)在參數(shù)列表中的位置。第一個(gè)參數(shù)由 "1$" 
  * 引用,第二個(gè)參數(shù)由 "2$" 引用,依此類推。 可選 flags 
  * 是修改輸出格式的字符集。有效標(biāo)志集取決于轉(zhuǎn)換類型。 可選 width 
  * 是一個(gè)非負(fù)十進(jìn)制整數(shù),表明要向輸出中寫入的最少字符數(shù)。 可選 precision 
  * 是一個(gè)非負(fù)十進(jìn)制整數(shù),通常用來(lái)限制字符數(shù)。特定行為取決于轉(zhuǎn)換類型。 所需 conversion 
  * 是一個(gè)表明應(yīng)該如何格式化參數(shù)的字符。給定參數(shù)的有效轉(zhuǎn)換集取決于參數(shù)的數(shù)據(jù)類型。 
  */ 
 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; // 時(shí) 
 return sFormatter.format(durationformat, timeArgs).toString().trim(); 
 } 

當(dāng)然,這里只是簡(jiǎn)單的介紹了下自定義進(jìn)度條,而該進(jìn)度條的樣式都沒(méi)有展現(xiàn)出來(lái),樣式讀者可以自己定義。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

景德镇市| 大英县| 武强县| 临夏市| 绍兴县| 新沂市| 双鸭山市| 白山市| 长泰县| 绵阳市| 布拖县| 定南县| 泰宁县| 德安县| 邮箱| 赤水市| 东山县| 墨玉县| 孝昌县| 黎城县| 宣汉县| 怀远县| 稷山县| 崇阳县| 宽甸| 乡城县| 岢岚县| 凌云县| 台湾省| 武陟县| 大理市| 临泉县| 台南县| 姜堰市| 万州区| 松桃| 诸城市| 北碚区| 布尔津县| 犍为县| 林芝县|