カスタムSeekBarを作成したいのですが、特定の場所(0〜10と90〜100の進行値周辺)で進行状況がSeekBarのつまみに従っていない場合にこの問題が発生します。これは、親指をプログレスバー内に留めるためにthumbOffset
を0に設定したために発生すると思います。 iPhone風のSeekBarを作りたい。
進行中のシークバー(問題ありません):
進行中のSeekBar5(問題あり):
進行中のシークバー50(問題ありません):
進行中のシークバー90(問題あり):
進行中のSeekBar100(問題ありません):
つまみの位置に基づいて進行状況を描画する場合、thumbOffset
は考慮されないようです。 thumbOffset
を親指の幅の半分に変更してみて、さまざまなパディングであらゆる種類の組み合わせを行いましたが、何も問題を解決しませんでした。 SOで見つけた他のすべてのソリューションも試しました。
ここに私が使っているXMLがあります:
SeekBarの定義:
<SeekBar
Android:id="@+id/scan_seekbar"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="0.5"
Android:max="100"
Android:progress="5"
Android:progressDrawable="@drawable/bg_seekbar"
Android:splitTrack="false"
Android:thumbOffset="0dp"
Android:thumb="@drawable/seekbar_thumb" />
ドローアブルbg_seekbar.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 Android:shape="rectangle">
<size Android:height="48dp"/>
<corners Android:radius="25dp"/>
<stroke Android:color="@color/semiLightBlue" Android:width="1dp"/>
</shape>
</item>
<item Android:id="@Android:id/progress">
<clip>
<shape Android:shape="rectangle">
<corners Android:radius="25dp"/>
<size Android:height="48dp"/>
<stroke Android:color="@color/colorAccent" Android:width="1dp"/>
<solid Android:color="@color/colorAccent"/>
</shape>
</clip>
</item>
</layer-list>
SeekBarサムseekbar_thumb.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item>
<shape Android:shape="rectangle">
<solid Android:color="@color/colorAccent"/>
<corners Android:radius="25dp"/>
<padding Android:bottom="8dp" Android:top="8dp" Android:left="16dp" Android:right="16dp" />
</shape>
</item>
<item Android:drawable="@drawable/ic_swipe_white" Android:gravity="center" Android:height="32dp" Android:width="44dp"/>
</layer-list>
他の誰かがこの問題に直面しましたか?
私はこの方法で問題を解決しました:
まず、親指が消えることはありません。進行状況が0または100のときに表示されます。オフセットを使用すると、親指が外側に飛び出します。
bg_seekbar_first.xml
進行状況<max/2の場合に使用します
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@Android:id/background"
Android:gravity="center_vertical|fill_horizontal">
<shape Android:shape="rectangle">
<corners Android:radius="24dp"/>
<size Android:height="48dp" />
<stroke Android:width="1dp" Android:color="@color/colorAccent"/>
</shape>
</item>
<item Android:id="@Android:id/progress"
Android:gravity="center_vertical|fill_horizontal">
<scale Android:scaleWidth="100%">
<shape Android:shape="rectangle"
Android:tint="@color/colorAccent">
<corners Android:radius="0dp"/>
<size Android:height="48dp" />
<solid Android:color="@color/colorAccent" />
</shape>
</scale>
</item>
</layer-list>
bg_seekbar_second.xml
これは、進行状況> max/2の場合に使用します
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@Android:id/background"
Android:gravity="center_vertical|fill_horizontal">
<shape Android:shape="rectangle">
<corners Android:radius="24dp"/>
<size Android:height="48dp" />
<stroke Android:width="1dp" Android:color="@color/colorAccent"/>
</shape>
</item>
<item Android:id="@Android:id/progress"
Android:gravity="center_vertical|fill_horizontal">
<scale Android:scaleWidth="100%">
<shape Android:shape="rectangle"
Android:tint="@color/colorAccent">
<corners Android:radius="24dp"/>
<size Android:height="48dp" />
<solid Android:color="@color/colorAccent" />
</shape>
</scale>
</item>
</layer-list>
seekbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item>
<shape Android:shape="rectangle">
<solid Android:color="@color/colorAccent"/>
<corners Android:topRightRadius="24dp"
Android:bottomRightRadius="24dp"/>
<padding Android:bottom="8dp" Android:top="8dp" Android:left="16dp" Android:right="16dp" />
</shape>
</item>
<item Android:drawable="@Android:drawable/ic_menu_close_clear_cancel" Android:gravity="center" Android:height="32dp" Android:width="44dp"/>
</layer-list>
親指の半径を変更しました
<com.google.Android.material.card.MaterialCardView
Android:layout_width="match_parent"
Android:layout_height="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
Android:layout_marginLeft="16dp"
Android:layout_marginRight="16dp"
app:cardCornerRadius="24dp"
Android:layout_marginTop="64dp"
>
<SeekBar
Android:id="@+id/scan_seekbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="0.5"
Android:max="100"
Android:paddingStart="0dp"
Android:paddingEnd="0dp"
Android:progress="1"
Android:progressDrawable="@drawable/bg_seekbar_first"
Android:splitTrack="false"
Android:thumb="@drawable/seekbar_thumb"
Android:thumbOffset="0dp"
/>
</com.google.Android.material.card.MaterialCardView>
この問題を解決するためにcardViewを追加しました:
scan_seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if(progress < seekBar?.max!! / 2){
seekBar.progressDrawable = ContextCompat.getDrawable(context!!,R.drawable.bg_seekbar_first)
}else{
seekBar.progressDrawable = ContextCompat.getDrawable(context!!,R.drawable.bg_seekbar_second)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
次に、このコード(Kotlin)onProgressChangedを使用してこの問題を解決しました:
そして結果:
うまくいくことを願っています。