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>