Android仿酷狗音乐SeekBar——样式篇

CasBlackbur 8年前
   <h2><strong>Android仿酷狗音乐SeekBar</strong></h2>    <h2><strong>需求:仿酷狗音乐SeekBar</strong></h2>    <p>直接上图,上代码</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/592301d0036356a9f1b5f47832a4696f.png"></p>    <p style="text-align:center">1903148-676fcbf2e5048392.png</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/fa2acb8362c633c31d3b20eb51c8e0fa.png"></p>    <p style="text-align:center">1903148-d3e5ab81fa2acd42.png</p>    <p>难点:用户点击或者移动是SeekBar滑块是改变滑块的图案</p>    <h3><strong>先画两种不同状态的滑块Thumb</strong></h3>    <p>平时状态:一个直径为10dp大小的白色的圆</p>    <p>slider_thumb_normal.xml</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <shape xmlns:android="http://schemas.android.com/apk/res/android"        android:shape="oval">        <size          android:width="10dp"          android:height="10dp" />    <solid android:color="#ffffffff" />  </shape></code></pre>    <p>按下状态:一个直径为10dp大小的白色的圆,背景是半透明的直径为40dp的圆</p>    <p>slider_thumb_pressed.xml</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <layer-list xmlns:android="http://schemas.android.com/apk/res/android">      <!-- 白色前景 -->      <item android:id="@android:id/secondaryProgress"          android:gravity="center"          android:bottom="15dp"          android:top="15dp"          android:right="15dp"          android:left="15dp">          <shape              android:shape="oval">              <size                  android:width="10dp"                  android:height="10dp" />              <solid android:color="#ffffffff" />          </shape>      </item>      <!-- 透明阴影 -->      <item android:id="@android:id/background"          android:gravity="center">          <shape              android:shape="oval">              <size                  android:height="40dp"                  android:width="40dp" />              <solid android:color="#96ffffff" />          </shape>      </item>  </layer-list></code></pre>    <h3><strong>画进度条</strong></h3>    <p>(不设置高度,由SeekBar自身控制,SeekBar控件android:layout_height="wrap_content")</p>    <p>play_seekbar_bg.xml</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <layer-list      xmlns:android="http://schemas.android.com/apk/res/android">      <item android:id="@android:id/background">          <shape>              <size                  android:height="2dp" />              <corners android:radius="5dp"/>              <solid android:color="#88ffffff" />          </shape>      </item>      <item          android:id="@android:id/secondaryProgress">          <clip>              <shape>                  <size                      android:height="2dp" />                  <corners android:radius="5dp"/>                  <solid android:color="#88ffffff" />              </shape>          </clip>      </item>      <item android:id="@android:id/progress">          <clip>              <shape>                  <size                      android:height="2dp"/>                  <corners android:radius="5dp"/>                  <solid android:color="#ffffffff" />              </shape>          </clip>      </item>  </layer-list></code></pre>    <h3><strong>SeekBar样式xml片段</strong></h3>    <pre>  <code class="language-java"><LinearLayout          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:layout_margin="8dp">          <TextView              android:layout_gravity="center"              android:layout_width="match_parent"              android:layout_height="wrap_content"              android:gravity="center"              android:id="@+id/seekbar_slider_time"              android:textColor="@color/color_white"              android:textAppearance="?android:attr/textAppearanceMedium"              android:visibility="invisible" />      </LinearLayout>      <LinearLayout          android:id="@+id/seekBar_layout"          android:layout_width="match_parent"          android:layout_height="40dp"          android:layout_marginStart="8dp"          android:layout_marginEnd="8dp"          android:gravity="center_vertical"          android:orientation="horizontal">          <TextView              android:id="@+id/tx_currentTime"              android:layout_width="40dp"              android:layout_height="wrap_content"              android:gravity="center"              android:textAppearance="?android:attr/textAppearanceSmall"              android:textColor="@color/color_white"/>          <SeekBar              android:id="@+id/seedBar"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_marginStart="-20dp"              android:layout_marginEnd="-20dp"              android:paddingStart="28dp"              android:paddingEnd="28dp"              android:background="@android:color/transparent"              android:gravity="center"              android:layout_weight="1"              android:splitTrack="false"              android:maxHeight="2dp"              android:progressDrawable="@drawable/play_seekbar_bg"              android:thumb="@drawable/slider_thumb_normal" />          <TextView              android:id="@+id/tx_maxTime"              android:layout_width="40dp"              android:layout_height="wrap_content"              android:gravity="center"              android:textAppearance="?android:attr/textAppearanceSmall"              android:textColor="@color/color_white"/>      </LinearLayout></code></pre>    <p>SeekBar样式关键点</p>    <ul>     <li> <p>android:maxHeight="2dp"——控制进度条高度</p> </li>     <li> <p>设置SeekBar控件边际,以便在滑块变大是可覆盖左右两边的控件,而不会被遮住</p> <pre>  <code class="language-java">android:layout_marginStart="-20dp"  android:layout_marginEnd="-20dp"  android:paddingStart="28dp"  android:paddingEnd="28dp"</code></pre> </li>     <li> <p>android:splitTrack="false"——控制滑块覆盖在进度条的上面</p> </li>     <li> <p>android:background="@android:color/transparent"——设置背景透明,去掉滑块变大时的周边光晕</p> </li>     <li> <p>android:progressDrawable="@drawable/play_seekbar_bg"——默认进度条</p> </li>     <li> <p>android:thumb="@drawable/slider_thumb_normal"——默认滑块</p> </li>    </ul>    <h2><strong>最关键的地方</strong></h2>    <p>使用SeekBar的setThumb方法动态设置滑块</p>    <p>代码</p>    <pre>  <code class="language-java">seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {              @Override              public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                  if(fromUser){                      Seekbar_slider_time.setText(updateCurrentTimeText(progress));                  }                  tx_currentTime.setText(updateCurrentTimeText(progress));                  if(progress == seekBar.getMax()){                      pauseIcon.setLayoutParams(miss);                      playIcon.setLayoutParams(show);                  }              }              @Override              public void onStartTrackingTouch(SeekBar seekBar) {                  Log.d(TAG,"onStartTrackingTouch");                  isUserPressThumb = true;                  Seekbar_slider_time.setVisibility(View.VISIBLE);                  //设置seekbar高度,解决第一次按下后Thumb被遮盖的问题                  ViewGroup.LayoutParams  lp = seekBar.getLayoutParams();                  lp.height *=4;                  seekBar.setLayoutParams(lp);                  //设置seekbarThumb相对位置可大于进度条15,保证thumb在变成40dp直径后可以滑动到进度条最末尾                  seekBar.setThumbOffset(15);                  seekBar.setThumb(Thumb_pressed);              }              @Override              public void onStopTrackingTouch(SeekBar seekBar) {                  Log.d(TAG,"onStopTrackingTouch");                  mi.seekTo(seekBar.getProgress());                  seekBar.setThumbOffset(0);                  seekBar.setThumb(Thumb_normal);                  Seekbar_slider_time.setVisibility(View.INVISIBLE);                  isUserPressThumb = false;              }          });</code></pre>    <p>在用户开始按下滑块时onStartTrackingTouch</p>    <p>//设置seekbar高度,解决部分手机第一次按下后Thumb因seekbar高度被遮盖的问题</p>    <p>ViewGroup.LayoutParams lp = seekBar.getLayoutParams();</p>    <p>lp.height *=4; //原先是10dp,需要增大至40dp,因为改变后的图案直径大小为40dp</p>    <p>seekBar.setLayoutParams(lp);</p>    <p>//设置seekbarThumb相对位置可大于进度条15,保证thumb在变成40dp直径后可以滑动到进度条最末尾</p>    <p>seekBar.setThumbOffset(15);</p>    <p>//改变滑块图案</p>    <p>seekBar.setThumb(Thumb_pressed);</p>    <p>在用户按下滑块结束后onStopTrackingTouch,恢复滑块及seekbar高度</p>    <p>seekBar.setThumbOffset(0);</p>    <p>seekBar.setThumb(Thumb_normal);</p>    <h2><strong>踩坑过程</strong></h2>    <p>使用selector的xml文件设置SeekBar的android:thumb属性设置滑块</p>    <p>play_seekbar_thumb.xml</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="UTF-8"?>  <selector xmlns:android="http://schemas.android.com/apk/res/android"         android:constantSize="false"         android:variablePadding="false">         <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/slider_thumb_normal" />         <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/slider_thumb_pressed" />         <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/slider_thumb_pressed" />         <item android:drawable="@drawable/slider_thumb_normal" />  </selector></code></pre>    <p>坑:有些手机上按下或者移动滑块,滑块是变大了,但是由于SeekBar高度还是原来的,导致滑块被压扁成椭圆</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/7f00c5361094</p>    <p> </p>