android通過代碼實現的多布局專題及常見問題 - CSDN

2021-01-07 CSDN技術社區

Seekbar常規使用方式通過xml布局方式實現,但是由於我們的是sdk,不能有xml布局,所以SeekBar使用純代碼實現。但是這樣就遇到了很多問題。
首先是SeekBar設置setProgressDrawable問題。因為我們的是視頻播放器,所以這個SeekBar需要有背景、緩衝進度和播放進度,最好的方法就是用layer-list 的xml布局實現,類似這樣:

<?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> <solid android:color="#cc999999" /> <size android:height="3dp" /> <corners android:radius="1.5dip" /> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <solid android:color="#9f4ef1" /> <size android:height="3dp" /> <corners android:radius="1.5dip" /> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <solid android:color="#0add2c" /> <size android:height="3dp" /> <corners android:radius="1.5dip" /> </shape> </clip> </item></layer-list>

這是正常的xml布局樣式,這樣的布局我們需要用java純代碼實現,如下:

Drawable[] drawables = new Drawable[3] GradientDrawable roundRect = new GradientDrawable() roundRect.setShape(GradientDrawable.RECTANGLE) roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor1)) roundRect.setSize(1,FormatUtils.dip2px(1,context)) roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context)) drawables[0] = roundRect roundRect = new GradientDrawable() roundRect.setShape(GradientDrawable.RECTANGLE) roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor3)) roundRect.setSize(1,FormatUtils.dip2px(1,context)) roundRect.setCornerRadius( FormatUtils.dip2px(1.5f,context)) ClipDrawable clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL) drawables[1] =clipDrawable roundRect = new GradientDrawable() roundRect.setShape(GradientDrawable.RECTANGLE) roundRect.setColor(Color.parseColor(ViewUtils.getInstance().colorProgress)) roundRect.setSize(1,FormatUtils.dip2px(1,context)) roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context)) clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL) drawables[2] = clipDrawable LayerDrawable layerDrawable = new LayerDrawable(drawables) layerDrawable.setId(0,android.R.id.background) layerDrawable.setId(1,android.R.id.secondaryProgress) layerDrawable.setId(2,android.R.id.progress)

然後直接SeekBar.setProgressDrawable就可以。

第二個問題是,SeekBar高度問題,這個才是最坑的,研究了很多,SeekBar如果用xml布局會有兩個方法android:maxHeight="4dp"和android:minHeight="4dp",但是如果是java寫,就只有progressBar.setMinimumHeight(FormatUtils.dip2px(1,context));,用來設置最小高度,這樣的話就有一個問題,如果你SeekBar設置seekBar.setThumb( bitmapDrawable);哪麼SeekBar的進度條高度也會變得和Thumb一樣高,會撐滿。這裡有兩個解決辦法:
一是在6.0以上的手機適用,就是在上面設置layerDrawable代碼後面再加兩句

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { layerDrawable.setLayerHeight(0,FormatUtils.dip2px(2,context)) layerDrawable.setLayerHeight(1,FormatUtils.dip2px(2,context)) layerDrawable.setLayerHeight(2,FormatUtils.dip2px(2,context)) layerDrawable.setLayerGravity(0,Gravity.CENTER_VERTICAL) layerDrawable.setLayerGravity(1,Gravity.CENTER_VERTICAL) layerDrawable.setLayerGravity(2,Gravity.CENTER_VERTICAL) }

整體是這樣:

public static Drawable genSeekProgressDrawable(Context context) { Drawable[] drawables = new Drawable[3] GradientDrawable roundRect = new GradientDrawable() roundRect.setShape(GradientDrawable.RECTANGLE) roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor1)) roundRect.setSize(1,FormatUtils.dip2px(1,context)) roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context)) drawables[0] = roundRect roundRect = new GradientDrawable() roundRect.setShape(GradientDrawable.RECTANGLE) roundRect.setColor(Color.parseColor(ViewUtils.getInstance().progressColor3)) roundRect.setSize(1,FormatUtils.dip2px(1,context)) roundRect.setCornerRadius( FormatUtils.dip2px(1.5f,context)) ClipDrawable clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL) drawables[1] =clipDrawable roundRect = new GradientDrawable() roundRect.setShape(GradientDrawable.RECTANGLE) roundRect.setColor(Color.parseColor(ViewUtils.getInstance().colorProgress)) roundRect.setSize(1,FormatUtils.dip2px(1,context)) roundRect.setCornerRadius(FormatUtils.dip2px(1.5f,context)) clipDrawable = new ClipDrawable(roundRect, Gravity.LEFT, VERTICAL) drawables[2] = clipDrawable LayerDrawable layerDrawable = new LayerDrawable(drawables) layerDrawable.setId(0,android.R.id.background) layerDrawable.setId(1,android.R.id.secondaryProgress) layerDrawable.setId(2,android.R.id.progress) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { layerDrawable.setLayerHeight(0,FormatUtils.dip2px(2,context)) layerDrawable.setLayerHeight(1,FormatUtils.dip2px(2,context)) layerDrawable.setLayerHeight(2,FormatUtils.dip2px(2,context)) layerDrawable.setLayerGravity(0,Gravity.CENTER_VERTICAL) layerDrawable.setLayerGravity(1,Gravity.CENTER_VERTICAL) layerDrawable.setLayerGravity(2,Gravity.CENTER_VERTICAL) } return layerDrawable }

二是適配所有的手機,這樣的話我沒有找到好的方法,只能用反射去修改SeekBar的父類的父類progressBar的最大高度,mMaxHeight的值,這個就是設置SeekBar的最大高度的值,xml代碼android:maxHeight="4dp"其實改變的就是這個的值。
代碼也很簡單:

try { Class<?> superclass = seekBar.getClass().getSuperclass().getSuperclass(); Field mMaxHeight = superclass.getDeclaredField("mMaxHeight"); mMaxHeight.setAccessible(true); mMaxHeight.set(seekBar,FormatUtils.dip2px(2,context)); } catch (Exception e) { e.printStackTrace(); }

其實最好的方法就是兩個一起用,6.0以下用反射,6.0以上用layerDrawable的方法去實現。這是我個人研究的辦法,網上也沒有實現的辦法,找了很久。如果有更好的求告知啊!!!!!

相關焦點

  • android布局詳解專題及常見問題 - CSDN
    Android 布局詳解1.重用布局當一個布局文件被多處使用時,最好<include>標籤來重用布局。  <include android:id=」@+id/cell3 layout=」@layout/workspace_screen」 /></LinearLayout>  上面的代碼中的<include>標籤還使用了一個android:id屬性,實際上,該屬性指定的是workspace_screen.xml布局文件中的根節點的android
  • android 不同大小的屏幕專題及常見問題 - CSDN
    本文將告訴你如何讓你的應用程式支持各種不同屏幕大小,主要通過以下幾種辦法:讓你的布局能充分的自適應屏幕根據屏幕的配置來加載合適的UI布局確保正確的布局應用在正確的設備屏幕上提供可以根據屏幕大小自動伸縮的圖片使用 "wrap_content" 和 "match_parent" 為了確保你的布局能夠自適應各種不同屏幕大小
  • android 復用 布局優化專題及常見問題 - CSDN
    在布局優化中,Androi的官方提到了這三種布局<include />、<merge />、<ViewStub />,並介紹了這三種布局各有的優勢,下面也是簡單說一下怎麼使用.
  • bootstrap 寬度 自適應布局專題及常見問題 - CSDN
    ,最常見的就是使用float來實現。float浮動布局的缺點是浮動後會造成文本環繞等效果,以及需要及時清除浮動。解決辦法是在left元素上設置margin-right: -100px[缺點2]當右側容器中有元素清除浮動時,會使該元素不與左側浮動元素同行,從而出現文字下沉現象【2】float + margin + (fix)(fix)代表增加結構,為了解決上述方法中的兩個缺點,可以通過增加結構來實現。自適應的一列外側增加一層結構.rightWrap並設置浮動。
  • android grid布局專題及常見問題 - CSDN
    通過將 CSS 規則應用於 父元素 (成為 Grid Container 網格容器)和其 子元素(成為 Grid Items 網格項),你就可以輕鬆使用 Grid (網格) 布局。另一方面,Internet Explorer 10和11支持它,但是是一個過時的語法實現。 現在是時候使用 Grid 布局網頁了!
  • android啟動頁設計專題及常見問題 - CSDN
    轉載請註明出處:http://blog.csdn.net/wangjihuanghun/article/details/63255144啟動頁幾乎成為了每個app的標配,有些商家在啟動頁中增加了開屏廣告以此帶來更多的收入。
  • android tv放大專題及常見問題 - CSDN
    在tv上開發gridview有焦點放大這個效果還是很普遍的做法,今天就講下這個實現方案,當然要實現這個效果有很多種,我這裡只是講其中的一種實現方案,也是比較簡單而且容易看懂的一個,首先看下效果圖是怎麼樣的?
  • android藍牙框架專題及常見問題 - CSDN
    代碼來源於Android P,本文相關代碼:client:frameworks/base/core/java/android/bluetooth/*system/bt/binder/android/bluetooth/**.aidlservie:framework/base/services/core/java/com/android/server
  • jquery實現響應式布局專題及常見問題 - CSDN
    使用 jQuery Mobile 和 CSS3 實現響應式設計創建可以適應每個用戶的屏幕解析度的 Web 頁面布局使用媒體類型的一種常見方式是為桌面計算機屏幕和 Web 頁面的列印版本分別定義單獨的樣式表。CSS3 通過引進媒體查詢,將設備相關的編碼措施這個概念再推進了一步。媒體查詢可以用於確定與 Web 頁面交互的設備類型,並使開發人員能夠確定正在查看 Web 頁面的設備的物理屬性。
  • android 從後臺啟動頁面專題及常見問題 - CSDN
    下面就實現方式進行詳細介紹。layout.xml首先創建此頁面的布局文件:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
  • android藍牙相關框架專題及常見問題 - CSDN
    代碼來源於Android P,本文相關代碼:client:frameworks/base/core/java/android/bluetooth/*system/bt/binder/android/bluetooth/**.aidlservie:framework/base/services/core/java/com/android/server/BluetoothService.java
  • android水平布局和垂直布局 - CSDN
    一、線性布局(LinearLayout)線性布局:線性布局是我們在開發中最常見的布局方式之一,線性布局可以分為水平線性布局和垂直線性布局這兩種布局方式線性布局的屬性(決定布局中元素的位置和布局):android:layout_gravity ( 是本元素相對於父元素的對齊方式 )android:gravity
  • android 首次打開判斷專題及常見問題 - CSDN
    前言用真機運行appium代碼,首次打開app有的手機會出現權限彈窗問題,一般這種彈窗都是在引導頁前面或者引導頁後面出現。權限彈窗上面的按鈕都是固定的,只需要定位到「始終允許」按鈕,點擊確定就可以了。還有一個問題是這種彈窗的個數不確定,有的app是2個有的是3個,為了解決這個問題,可以專門寫個判斷方法。
  • android app被殺原因專題及常見問題 - CSDN
    Android5.1.1源碼 - App服務進程被殺後自動重啟的原因@(Android研究)[App服務重啟][TOC]前言當通過分析長按HOME鍵清理App最終會執行到ActivityManagerService.cleanUpRemovedTaskLocked方法中,ActivityManagerService類在文件"frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java"中,
  • android 進度條顯示時間專題及常見問題 - CSDN
    定義一個attrs.xml自定義CircleProgressViewpackage com.sample.circleprogressview.widget;import android.animation.ValueAnimator;import android.content.Context
  • class ios 布局專題及常見問題 - CSDN
    Autolayout(以及iOS8中新增的sizeclass)是為了解決這些UI可視單元或者元素是怎樣布局、排列的問題。在過去只有iPhone4的時候,我們可以在代碼裡將沒一個可視單元的位置寫死,這樣是沒問題的,但隨著iPhone5、6的發布,屏幕尺寸有了越來越多中可能,未來不排除更多尺寸的iPhone發布出來,這就要求我們的APP的UI元素具有在屏幕尺寸不同的設備上具有一定動態的可調性,已實現較好的UI展示效果。
  • android 自定義view大小專題及常見問題 - CSDN
    它本質上是一個FrameLayoutViewRoot在Activtiy啟動時創建,負責管理、布局、渲染窗口UI等等對於多View的視圖,結構是樹形結構:最頂層是ViewGroup,ViewGroup下可能有多個ViewGroup或View,如下圖:一定要記住:無論是measure過程、layout過程還是draw過程,永遠都是從View
  • Android一些你需要知道的布局優化技巧
    唯鹿的博客地址:http://blog.csdn.net/qq_17766199今天分享一些layout布局書寫中的一些技巧,希望看過之後你也一樣可以寫出性價比高的布局。我個人的目標是用最少的View寫出一樣效果的布局。因為我相信View的數量減少伴隨著的就是層級的減少。從而達到結構清晰,渲染速度快的效果。順著這個邏輯,我將優化分為重用、合併、按需載入。
  • android 布局 覆蓋 - CSDN
    按照正常使用點擊item的空白區域選擇時沒有問題的,但是當你單獨點擊checkbox時,CheckBox沒有相應的點擊事件,而父控制項也沒有捕獲。導致的問題是:顯示的是選擇了,但是實際上並沒有捕獲點擊事件。
  • 安卓免費學習的博客,github,CSDN,視頻教程,一網打盡!
    /PaicHyperionDev/MobileDevWeekly【Bus Weekly】專題集合每周精選推:http://www.apkbus.com/search.php?BorePlugin:根據布局自動生成findViewById,onClick等代碼。Android Parcelable code generator:JavaBean序列化,快速實現Parcelable接口。GenerateSerialVersionUID:實現Serializable序列化Bean。