丸みを帯びたプログレスバーを作成しようとしています。これが私が達成したいことです
灰色の背景の輪があります。その上に、青い進捗バーが表示されます。進捗バーは60または何秒でも0から360までの円軌道で移動します。
これが私のサンプルコードです。
<ProgressBar
Android:id="@+id/ProgressBar"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
style="?android:attr/progressBarStyleLarge"
Android:indeterminateDrawable="@drawable/progressBarBG"
Android:progress="50"
/>
これを行うには、描画可能な「progressBarBG」で、レイヤリストを作成し、そのレイヤリスト内に、表示されているように2つの項目を指定します。
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@Android:id/background">
<shape
Android:shape="ring"
Android:innerRadius="64dp"
Android:thickness="8dp"
Android:useLevel="false">
<solid Android:color="@color/grey" />
</shape>
</item>
<item Android:id="@Android:id/progress">
<clip>
<shape
Android:shape="ring"
Android:innerRadius="64dp"
Android:thickness="8dp"
Android:useLevel="false">
<solid Android:color="@color/blue" />
</shape>
</clip>
</item>
これで、最初の灰色の輪が正しく生成されました。しかし青い輪はドロウアブルの左から始まり、線形プログレスバーが機能するのと同じように右に進みます。これは、方向を示す赤い矢印で、50%の進捗状況で表示される方法です。
予想通り、青いプログレスバーを円を描くように移動します。
これが私の2つの解決策です。
簡単な答え:
layer-list
を作成する代わりに、2つのファイルに分けました。 1つはProgressBar
name__、もう1つはその背景です。
これはProgressDrawable
name__ファイル(@drawableフォルダー)です。circular_progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:fromDegrees="270"
Android:toDegrees="270">
<shape
Android:innerRadiusRatio="2.5"
Android:shape="ring"
Android:thickness="1dp"
Android:useLevel="true"><!-- this line fixes the issue for Lollipop api 21 -->
<gradient
Android:angle="0"
Android:endColor="#007DD6"
Android:startColor="#007DD6"
Android:type="sweep"
Android:useLevel="false" />
</shape>
</rotate>
そしてこれはそのbackground
name __(@ drawable folder)のためのものです:circle_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="ring"
Android:innerRadiusRatio="2.5"
Android:thickness="1dp"
Android:useLevel="false">
<solid Android:color="#CCC" />
</shape>
そして最後に、作業しているレイアウトの内側に、
<ProgressBar
Android:id="@+id/progressBar"
Android:layout_width="200dp"
Android:layout_height="200dp"
Android:indeterminate="false"
Android:progressDrawable="@drawable/circular_progress_bar"
Android:background="@drawable/circle_shape"
style="?android:attr/progressBarStyleHorizontal"
Android:max="100"
Android:progress="65" />
これが結果です。
長い答え:
Android.view.View
を継承するカスタムビューを使う
これが完全なプロジェクトです github上
私は簡単な方法でやった:
スクリーンショットも同じようにチェックしてください。
CustomProgressBarActivity.Java:
public class CustomProgressBarActivity extends AppCompatActivity {
private TextView txtProgress;
private ProgressBar progressBar;
private int pStatus = 0;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_progressbar);
txtProgress = (TextView) findViewById(R.id.txtProgress);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
new Thread(new Runnable() {
@Override
public void run() {
while (pStatus <= 100) {
handler.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(pStatus);
txtProgress.setText(pStatus + " %");
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pStatus++;
}
}
}).start();
}
}
activity_custom_progressbar.xml:
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.skholingua.Android.custom_progressbar_circular.MainActivity" >
<RelativeLayout
Android:layout_width="wrap_content"
Android:layout_centerInParent="true"
Android:layout_height="wrap_content">
<ProgressBar
Android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
Android:layout_width="250dp"
Android:layout_height="250dp"
Android:layout_centerInParent="true"
Android:indeterminate="false"
Android:max="100"
Android:progress="0"
Android:progressDrawable="@drawable/custom_progressbar_drawable"
Android:secondaryProgress="0" />
<TextView
Android:id="@+id/txtProgress"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignBottom="@+id/progressBar"
Android:layout_centerInParent="true"
Android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</RelativeLayout>
custom_progressbar_drawable.xml:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:fromDegrees="-90"
Android:pivotX="50%"
Android:pivotY="50%"
Android:toDegrees="270" >
<shape
Android:shape="ring"
Android:useLevel="false" >
<gradient
Android:centerY="0.5"
Android:endColor="#FA5858"
Android:startColor="#0099CC"
Android:type="sweep"
Android:useLevel="false" />
</shape>
</rotate>
これがお役に立てば幸いです。
私は Androidの円形のプログレスバー ここに私のブログで詳細な例を書きました demonuts.com 。あなたは完全なソースコードと説明をそこで好むこともできます。
ライブラリを使わない純粋なコードで、円の内側にパーセンテージの付いた円形のプログレスバーを作成しました。
最初にcircular.xml
という名前の描画可能ファイルを作成します。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@Android:id/secondaryProgress">
<shape
Android:innerRadiusRatio="6"
Android:shape="ring"
Android:thicknessRatio="20.0"
Android:useLevel="true">
<gradient
Android:centerColor="#999999"
Android:endColor="#999999"
Android:startColor="#999999"
Android:type="sweep" />
</shape>
</item>
<item Android:id="@Android:id/progress">
<rotate
Android:fromDegrees="270"
Android:pivotX="50%"
Android:pivotY="50%"
Android:toDegrees="270">
<shape
Android:innerRadiusRatio="6"
Android:shape="ring"
Android:thicknessRatio="20.0"
Android:useLevel="true">
<rotate
Android:fromDegrees="0"
Android:pivotX="50%"
Android:pivotY="50%"
Android:toDegrees="360" />
<gradient
Android:centerColor="#00FF00"
Android:endColor="#00FF00"
Android:startColor="#00FF00"
Android:type="sweep" />
</shape>
</rotate>
</item>
</layer-list>
今すぐあなたのactivity_main.xml
に以下を追加してください:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/dialog"
tools:context="com.example.parsaniahardik.progressanimation.MainActivity">
<ProgressBar
Android:id="@+id/circularProgressbar"
style="?android:attr/progressBarStyleHorizontal"
Android:layout_width="250dp"
Android:layout_height="250dp"
Android:indeterminate="false"
Android:max="100"
Android:progress="50"
Android:layout_centerInParent="true"
Android:progressDrawable="@drawable/circular"
Android:secondaryProgress="100"
/>
<ImageView
Android:layout_width="90dp"
Android:layout_height="90dp"
Android:background="@drawable/whitecircle"
Android:layout_centerInParent="true"/>
<TextView
Android:id="@+id/tv"
Android:layout_width="250dp"
Android:layout_height="250dp"
Android:gravity="center"
Android:text="25%"
Android:layout_centerInParent="true"
Android:textColor="@color/colorPrimaryDark"
Android:textSize="20sp" />
</RelativeLayout>
activity_main.xml
では、白い背景を持つ円形の画像を1つ使用して、白い背景をパーセントで表示しています。これがそのイメージです。
この画像の色を変更して、パーセントテキストの周囲にカスタムの色を設定できます。
最後に次のコードをMainActivity.Java
に追加します。
import Android.content.res.Resources;
import Android.graphics.drawable.Drawable;
import Android.os.Handler;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.view.animation.DecelerateInterpolator;
import Android.widget.ProgressBar;
import Android.widget.TextView;
public class MainActivity extends AppCompatActivity {
int pStatus = 0;
private Handler handler = new Handler();
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.circular);
final ProgressBar mProgress = (ProgressBar) findViewById(R.id.circularProgressbar);
mProgress.setProgress(0); // Main Progress
mProgress.setSecondaryProgress(100); // Secondary Progress
mProgress.setMax(100); // Maximum Progress
mProgress.setProgressDrawable(drawable);
/* ObjectAnimator animation = ObjectAnimator.ofInt(mProgress, "progress", 0, 100);
animation.setDuration(50000);
animation.setInterpolator(new DecelerateInterpolator());
animation.start();*/
tv = (TextView) findViewById(R.id.tv);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (pStatus < 100) {
pStatus += 1;
handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
mProgress.setProgress(pStatus);
tv.setText(pStatus + "%");
}
});
try {
// Sleep for 200 milliseconds.
// Just to display the progress slowly
Thread.sleep(8); //thread will take approx 1.5 seconds to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
水平方向のプログレスバーを作成したい場合は、このリンクをたどってください。ソースコードを使った多くの有益な例があります。
http://www.skholingua.com/Android-basic/user-interface/form-widgets/progressbar
GitHubでオープンソースライブラリを実現しましたCircularProgressBar それはあなたが可能な限り最も単純な方法を望んでいることを正確に行います:
循環ProgressBarをレイアウトXMLにCircularProgressBarを追加し、CircularProgressBarライブラリを追加するには)あなたのプロジェクターで、またはあなたはGradleを通してそれをつかむこともできます:
compile 'com.mikhaellopez:circularprogressbar:1.0.0'
<com.mikhaellopez.circularprogressbar.CircularProgressBar
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:background_progressbar_color="#FFCDD2"
app:background_progressbar_width="5dp"
app:progressbar_color="#F44336"
app:progressbar_width="10dp" />
CircularProgressBarを変更するには、XMLで次のプロパティを使用する必要があります。
プロパティ:
app:progress
(integer)>>デフォルト0app:progressbar_color
(color)>>デフォルトのBLACKapp:background_progressbar_color
(color)>>デフォルトGREYapp:progressbar_width
(ディメンション)>>デフォルト7dpapp:background_progressbar_width
(dimension)>>デフォルトの3dpCircularProgressBar circularProgressBar = (CircularProgressBar)findViewById(R.id.yourCircularProgressbar);
circularProgressBar.setColor(ContextCompat.getColor(this, R.color.progressBarColor));
circularProgressBar.setBackgroundColor(ContextCompat.getColor(this, R.color.backgroundProgressBarColor));
circularProgressBar.setProgressBarWidth(getResources().getDimension(R.dimen.progressBarWidth));
circularProgressBar.setBackgroundProgressBarWidth(getResources().getDimension(R.dimen.backgroundProgressBarWidth));
int animationDuration = 2500; // 2500ms = 2,5s
circularProgressBar.setProgressWithAnimation(65, animationDuration); // Default duration = 1500ms
このライブラリをフォークまたはダウンロードする>> https://github.com/lopspower/CircularProgressBar
私は新しいのでコメントはできませんが、怠惰な修正を共有することを考えました。私もPedramのオリジナルのアプローチを使用して、そしてちょうど同じLollipop問題に出くわしました。しかし、 alanv が別の投稿で1行修正されました。そのある種のバグやAPI21の見落とし。サークルの進捗状況xmlに文字通りAndroid:useLevel="true"
を追加するだけです。 Pedramの新しいアプローチはまだ適切な解決策ですが、私は怠惰な修正プログラムも共有すると思いました。
https://github.com/passsy/Android-HoloCircularProgressBar はこれを行うライブラリの一例です。 Tenfour04が述べたように、これは箱から出して直接サポートされていないという点で、ややカスタムである必要があります。このライブラリが望みどおりに動作しない場合は、フォークして詳細を変更して好みに合うようにすることができます。他の人が再利用できるものを実装した場合は、プルリクエストを送信してマージすることもできます。
この方法を試してビットマップを作成し、それを画像ビューに設定します。
private void circularImageBar(ImageView iv2, int i) {
Bitmap b = Bitmap.createBitmap(300, 300,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
Paint paint = new Paint();
Paint.setColor(Color.parseColor("#c4c4c4"));
Paint.setStrokeWidth(10);
Paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(150, 150, 140, Paint);
Paint.setColor(Color.parseColor("#FFDB4C"));
Paint.setStrokeWidth(10);
Paint.setStyle(Paint.Style.FILL);
final RectF oval = new RectF();
Paint.setStyle(Paint.Style.STROKE);
oval.set(10,10,290,290);
canvas.drawArc(oval, 270, ((i*360)/100), false, Paint);
Paint.setStrokeWidth(0);
Paint.setTextAlign(Align.CENTER);
Paint.setColor(Color.parseColor("#8E8E93"));
Paint.setTextSize(140);
canvas.drawText(""+i, 150, 150+(Paint.getTextSize()/3), Paint);
iv2.setImageBitmap(b);
}
以下は、サークルの進行状況を表示する簡単なカスタムビューです。プロジェクトに合わせて、さらに変更および最適化できます。
class CircleProgressBar @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val backgroundWidth = 10f
private val progressWidth = 20f
private val backgroundPaint = Paint().apply {
color = Color.LTGRAY
style = Paint.Style.STROKE
strokeWidth = backgroundWidth
isAntiAlias = true
}
private val progressPaint = Paint().apply {
color = Color.RED
style = Paint.Style.STROKE
strokeWidth = progressWidth
isAntiAlias = true
}
var progress: Float = 0f
set(value) {
field = value
invalidate()
}
private val oval = RectF()
private var centerX: Float = 0f
private var centerY: Float = 0f
private var radius: Float = 0f
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
centerX = w.toFloat() / 2
centerY = h.toFloat() / 2
radius = w.toFloat() / 2 - progressWidth
oval.set(centerX - radius,
centerY - radius,
centerX + radius,
centerY + radius)
super.onSizeChanged(w, h, oldw, oldh)
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.drawCircle(centerX, centerY, radius, backgroundPaint)
canvas?.drawArc(oval, 270f, 360f * progress, false, progressPaint)
}
}
使用例
xml
<com.example.androidcircleprogressbar.CircleProgressBar
Android:id="@+id/circle_progress"
Android:layout_width="200dp"
Android:layout_height="200dp" />
コトリン
class MainActivity : AppCompatActivity() {
val TOTAL_TIME = 10 * 1000L
override fun onCreate(savedInstanceState: Bundle?) {
...
timeOutRemoveTimer.start()
}
private var timeOutRemoveTimer = object : CountDownTimer(TOTAL_TIME, 10) {
override fun onFinish() {
circle_progress.progress = 1f
}
override fun onTick(millisUntilFinished: Long) {
circle_progress.progress = (TOTAL_TIME - millisUntilFinished).toFloat() / TOTAL_TIME
}
}
}
結果
変化する
Android:useLevel="false"
に
Android:useLevel="true"
id="@Android:id/progress
を持つ2番目のsahpeの場合
うまくいけばいい
@Pedram、あなたの古い解決策はLollipopでも実際にはうまく機能します(そしてリモートビューを含めて、どこでも使えるので新しい解決策よりも優れています):circular_progress_bar.xml
コードをこれに変更するだけです:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:fromDegrees="270"
Android:toDegrees="270">
<shape
Android:innerRadiusRatio="2.5"
Android:shape="ring"
Android:thickness="1dp"
Android:useLevel="true"> <!-- Just add this line -->
<gradient
Android:angle="0"
Android:endColor="#007DD6"
Android:startColor="#007DD6"
Android:type="sweep"
Android:useLevel="false" />
</shape>
</rotate>
package com.example.ankitrajpoot.myapplication;
import Android.app.Activity;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.ProgressBar;
public class MainActivity extends Activity {
private ProgressBar spinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner=(ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.VISIBLE);
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/loadingPanel"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center">
<ProgressBar
Android:id="@+id/progressBar"
Android:layout_width="48dp"
style="?android:attr/progressBarStyleLarge"
Android:layout_height="48dp"
Android:indeterminateDrawable="@drawable/circular_progress_bar"
Android:indeterminate="true" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<rotate
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:pivotX="50%"
Android:pivotY="50%"
Android:fromDegrees="0"
Android:toDegrees="1080">
<shape
Android:shape="ring"
Android:innerRadiusRatio="3"
Android:thicknessRatio="8"
Android:useLevel="false">
<size
Android:width="56dip"
Android:height="56dip" />
<gradient
Android:type="sweep"
Android:useLevel="false"
Android:startColor="@Android:color/transparent"
Android:endColor="#1e9dff"
Android:angle="0"
/>
</shape>
</rotate>