Android 实现一个带有两个剪辑文本视图的进度条
Android implement a progressBar with two clip textview on it
我要实现一个带有两个剪辑文本视图的进度条。
就像是:
我用了一些技巧(使用paddingEnd/paddingStart、back/front textview来实现textview的剪辑效果)来实现它:
// part of activity
TextView leftFrontText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(this, R.layout.test_page_layout, containerLayout);
View progressBar = view.findViewById(R.id.progress_bar);
leftFrontText = view.findViewById(R.id.left_front_textview);
int progress = 59;
ValueAnimator va = ValueAnimator.ofFloat(0f, progress);
int mDuration = 1000;
va.setDuration(mDuration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float)animation.getAnimatedValue();
setViewWidth(progressBar, (int)value);
setLeftFrontTextViewPadding((int)value);
}
});
// va.addListener(new Animator.AnimatorListener() {
// @Override
// public void onAnimationStart(Animator animation) {
//
// }
//
// @Override
// public void onAnimationEnd(Animator animation) {
// setLeftFrontTextViewPadding(progress);
// }
//
// @Override
// public void onAnimationCancel(Animator animation) {
//
// }
//
// @Override
// public void onAnimationRepeat(Animator animation) {
//
// }
// });
va.start();
}
private void setViewWidth(View view, int dp) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = ThemeUtil.dpToPx(this, dp);
view.setLayoutParams(layoutParams);
}
private void setLeftFrontTextViewPadding(int progressBarDp) {
int marginStart = ThemeUtil.dpToPx(TestPageActivity.this, 12);
leftFrontText.post(new Runnable() {
@Override
public void run() {
int textViewLength = leftFrontText.getWidth();
int progressbarDistance = ThemeUtil.dpToPx(TestPageActivity.this, progressBarDp);
if (textViewLength >= 0) {
int padding = marginStart + textViewLength - progressbarDistance;
leftFrontText.setPadding(0, 0, padding > 0 ? -padding : 0, 0);
}
}
});
}
布局为:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/rounded_corner_bg_for_cashlfow_homepage_category_cell"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
>
<TextView
android:id="@+id/left_bottom_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="Entertatinment"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="@color/grey1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<View
android:id="@+id/progress_bar"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="@drawable/rounded_corner_front_progreebar_homepage_category_cell"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="@+id/left_front_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|start"
android:text="Entertatinment"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="@color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<TextView
android:id="@+id/right_bottom_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="[=12=] / [=12=]"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:textColor="@color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
/>
<TextView
android:id="@+id/right_front_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="[=12=] / [=12=]"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:textColor="@color/black1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
android:paddingStart="0dp"
/>
</android.support.constraint.ConstraintLayout>
当我运行这段代码时,几乎达到了我想要的效果。但它有一个问题。 Textview在做动画的时候一直在闪烁,当动画结束的时候,textview的颜色有时会变成全白。
我认为 setLeftFrontTextViewPadding
的 leftFrontText.post()
中可能有问题,比如我如何获取 textview 的宽度。但我不太确定。谁能告诉我正确的方法吗?或者任何其他更好的方法来实现这种进度条。
为什么不尝试这种方法并利用 ConstraintLayout
的力量作为您的进度条:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parentview"
android:layout_width="360dp"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#ddddff"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<TextView
android:id="@+id/left_bottom_textview"
android:layout_width="180dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="Entertainment"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#404040"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/right_front_amount_textview"
android:layout_width="180dp"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="[=10=] / [=10=]"
android:maxLines="1"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="@+id/progress_bar"
android:layout_width="50dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#004090">
<TextView
android:id="@+id/left_front_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Entertainment"
android:singleLine="true"
android:textColor="#fff"
android:ellipsize="none"
android:layout_paddingStart="12dp"
android:layout_paddingLeft="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/right_bottom_amount_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical|end"
android:text="[=10=] / [=10=]"
android:layout_alignRight="@id/left_front_textview"
android:textColor="#ffffff"
android:layout_paddingEnd="12dp"
android:layout_paddingRight="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/left_front_textview"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
所以基本上我们会有:
父布局(parentview):具有固定的layout_width360dp
并包含初始的Grey TextViews
Progress 布局(progress_bar): 也有固定大小360dp
并包含前面White TextViews
因此我们将 Progress layout (progress_bar)
叠加在其父布局之上,并增加或减少 layout_width
以模拟不闪烁的进度:
下图显示了静态 layout_width 为 74dp
的进度布局;另请注意,根据上面提供的示例,progress layout_width
的范围可以是 1dp to max:360dp
或 1% to 100% of parentview width
.
我要实现一个带有两个剪辑文本视图的进度条。
就像是:
我用了一些技巧(使用paddingEnd/paddingStart、back/front textview来实现textview的剪辑效果)来实现它:
// part of activity
TextView leftFrontText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(this, R.layout.test_page_layout, containerLayout);
View progressBar = view.findViewById(R.id.progress_bar);
leftFrontText = view.findViewById(R.id.left_front_textview);
int progress = 59;
ValueAnimator va = ValueAnimator.ofFloat(0f, progress);
int mDuration = 1000;
va.setDuration(mDuration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float)animation.getAnimatedValue();
setViewWidth(progressBar, (int)value);
setLeftFrontTextViewPadding((int)value);
}
});
// va.addListener(new Animator.AnimatorListener() {
// @Override
// public void onAnimationStart(Animator animation) {
//
// }
//
// @Override
// public void onAnimationEnd(Animator animation) {
// setLeftFrontTextViewPadding(progress);
// }
//
// @Override
// public void onAnimationCancel(Animator animation) {
//
// }
//
// @Override
// public void onAnimationRepeat(Animator animation) {
//
// }
// });
va.start();
}
private void setViewWidth(View view, int dp) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = ThemeUtil.dpToPx(this, dp);
view.setLayoutParams(layoutParams);
}
private void setLeftFrontTextViewPadding(int progressBarDp) {
int marginStart = ThemeUtil.dpToPx(TestPageActivity.this, 12);
leftFrontText.post(new Runnable() {
@Override
public void run() {
int textViewLength = leftFrontText.getWidth();
int progressbarDistance = ThemeUtil.dpToPx(TestPageActivity.this, progressBarDp);
if (textViewLength >= 0) {
int padding = marginStart + textViewLength - progressbarDistance;
leftFrontText.setPadding(0, 0, padding > 0 ? -padding : 0, 0);
}
}
});
}
布局为:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/rounded_corner_bg_for_cashlfow_homepage_category_cell"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
>
<TextView
android:id="@+id/left_bottom_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="Entertatinment"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="@color/grey1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<View
android:id="@+id/progress_bar"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="@drawable/rounded_corner_front_progreebar_homepage_category_cell"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="@+id/left_front_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|start"
android:text="Entertatinment"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="@color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<TextView
android:id="@+id/right_bottom_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="[=12=] / [=12=]"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:textColor="@color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
/>
<TextView
android:id="@+id/right_front_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="[=12=] / [=12=]"
android:textSize="@dimen/main_text_size"
android:maxLines="1"
android:textColor="@color/black1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
android:paddingStart="0dp"
/>
</android.support.constraint.ConstraintLayout>
当我运行这段代码时,几乎达到了我想要的效果。但它有一个问题。 Textview在做动画的时候一直在闪烁,当动画结束的时候,textview的颜色有时会变成全白。
我认为 setLeftFrontTextViewPadding
的 leftFrontText.post()
中可能有问题,比如我如何获取 textview 的宽度。但我不太确定。谁能告诉我正确的方法吗?或者任何其他更好的方法来实现这种进度条。
为什么不尝试这种方法并利用 ConstraintLayout
的力量作为您的进度条:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parentview"
android:layout_width="360dp"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#ddddff"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<TextView
android:id="@+id/left_bottom_textview"
android:layout_width="180dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="Entertainment"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#404040"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/right_front_amount_textview"
android:layout_width="180dp"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="[=10=] / [=10=]"
android:maxLines="1"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="@+id/progress_bar"
android:layout_width="50dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#004090">
<TextView
android:id="@+id/left_front_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Entertainment"
android:singleLine="true"
android:textColor="#fff"
android:ellipsize="none"
android:layout_paddingStart="12dp"
android:layout_paddingLeft="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/right_bottom_amount_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical|end"
android:text="[=10=] / [=10=]"
android:layout_alignRight="@id/left_front_textview"
android:textColor="#ffffff"
android:layout_paddingEnd="12dp"
android:layout_paddingRight="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/left_front_textview"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
所以基本上我们会有:
父布局(parentview):具有固定的layout_width360dp
并包含初始的Grey TextViews
Progress 布局(progress_bar): 也有固定大小360dp
并包含前面White TextViews
因此我们将 Progress layout (progress_bar)
叠加在其父布局之上,并增加或减少 layout_width
以模拟不闪烁的进度:
下图显示了静态 layout_width 为 74dp
的进度布局;另请注意,根据上面提供的示例,progress layout_width
的范围可以是 1dp to max:360dp
或 1% to 100% of parentview width
.