안드로이드에서 원형 진행률 표시 줄을 만드는 방법?
둥근 진행률 막대를 만들려고합니다. 이것이 내가 달성하고 싶은 것입니다
회색 배경의 링이 있습니다. 그 위에 파란색 진행률 표시 줄이 나타나 60에서 또는 0 초에 원형 경로로 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"에서 레이어 목록을 만들고 해당 레이어 목록 안에 표시된대로 두 개의 항목을 제공합니다.
<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 % 진행률로 표시되는 방식입니다.
파란색 진행률 표시 줄을 예상대로 원형 경로로 이동하고 싶습니다.
여기 내 두 가지 해결책이 있습니다.
짧은 답변:
를 만드는 대신 layer-list
두 파일로 분리했습니다. 하나 ProgressBar
의 배경과 하나의 배경.
이것은이다 ProgressDrawable
파일 (@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
(@drawable 폴더)입니다 : 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>
이것이 도움이되기를 바랍니다.
내 블로그 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
필자는 흰색 배경의 원형 이미지를 사용 하여 백분율 주위에 흰색 배경을 표시했습니다. 이미지는 다음과 같습니다.
이 이미지의 색상을 변경하여 백분율 텍스트 주위에 사용자 정의 색상을 설정할 수 있습니다.
이제 마지막으로 다음 코드를 추가하십시오 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를 추가 할 수 있도록하려면 CircularProgressBar를 레이아웃 XML과 추가 CircularProgressBar 라이브러리를 프로젝터 또는 당신은 또한 Gradle을 통해 그것을 잡아 수 있습니다 :
compile 'com.mikhaellopez:circularprogressbar:1.0.0'
XML
<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
(정수) >> 기본 0app:progressbar_color
(칼라) >> 기본 BLACKapp:background_progressbar_color
(칼라) >> 기본 회색app:progressbar_width
(치수) >> 기본 7dpapp:background_progressbar_width
(치수) >> 기본 3dp
자바
CircularProgressBar 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 는 한 줄로 수정되었습니다. API21의 일종의 버그 또는 감독입니다. 말 그대로 android:useLevel="true"
서클 진행 xml에 추가 하십시오. 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
}
}
}
결과
@Pedram, 기존 솔루션은 실제로 롤리팝에서도 잘 작동합니다 (원격보기를 포함하여 모든 곳에서 사용할 수 있기 때문에 새로운 솔루션보다 낫습니다) 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>
변화
android:useLevel="false"
에
android:useLevel="true"
와 두 번째 sahpe id="@android:id/progress
그것이 작동하기를 바랍니다
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>
'development' 카테고리의 다른 글
호스트에 로그인하지 않고 IP에서 호스트 이름을 찾는 방법 (0) | 2020.07.06 |
---|---|
클로저 프로토콜에 대한 간단한 설명 (0) | 2020.07.06 |
자바 스크립트로 터치 스크린 장치 감지 (0) | 2020.07.06 |
html svg 객체를 클릭 가능한 링크로 만듭니다. (0) | 2020.07.06 |
onCheckChanged를 트리거하지 않고 Checkbox 값 변경 (0) | 2020.07.06 |