问题
I have a progressbar as shown in the following image. My problem is that I want to move the TextView that shows the current step of the progress, along with the progress.
So in the step 3/7 it should move with the progress. The inside drawable is a styled xml shape drawable.
rounded_corners_progress_bar
<?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>
<corners android:radius="8dp"/>
<solid android:color="@color/progressbarBgColor"/>
</shape>
</item>
<item android:id="@android:id/progress"
android:top="1dp"
android:bottom="1dp"
android:left="1dp"
android:right="1dp">
<scale android:scaleWidth="100%">
<shape>
<corners android:radius="8dp"/>
<solid android:color="?attr/colorAccent"/>
</shape>
</scale>
</item>
</layer-list>
Overall layout (It is an MVVMCross native Android project so local:MvxBind relate to that)
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<ProgressBar
android:id="@+id/determinateBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:progressDrawable="@drawable/rounded_corners_progress_bar"
local:MvxBind="Max TotalProgressSteps; Progress CurrentProgress"
/>
<TextView
android:text="1 / 7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/determinateBar"
android:layout_alignStart="@id/determinateBar"
android:paddingLeft="15dp"
android:id="@+id/steps" />
</RelativeLayout>
回答1:
I suggest take help of constraint layout which give you the best mechanism to implement First, create one constraint layout and put your progress bar inside it also put text view in which you want to set text amount process and move bias as per your process percent like bellow
Layout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:id="@+id/mConstraintLayout"
android:layout_height="wrap_content">
<ProgressBar
android:layout_width="match_parent"
android:id="@+id/mProgressBar"
android:layout_height="wrap_content" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:id="@+id/mTVValue"
android:text="7/10"
app:layout_constraintStart_toStartOf="@+id/mProgressBar"
app:layout_constraintEnd_toEndOf="@+id/mProgressBar"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
Then After doing the bellow code in your class
/**
* Method move progress label as per progress change
* @param constraintLayout constraint layout object
* @param textViewId text view id which you want to move also text id same which you used in design
* @param percentProgress Progress in percentages means total moved progress percent which from 100
*/
private void moveProgressPercent(ConstraintLayout constraintLayout,int textViewId,float percentProgress){
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.setHorizontalBias(textViewId, percentProgress / 100);
constraintSet.applyTo(constraintLayout);
}
As per the above view it like
ConstraintLayout constraintLayout=findViewById(R.id.mConstraintLayout);
moveProgressPercent(constraintLayout,R.id.mTVValue,25);
回答2:
This is my solution.
I created a class and extended it with RelativeLayout
, inflated the layout (which you can see in the above question).
Added a Listener to listen to layout changes _progressBar.ViewTreeObserver.GlobalLayout += ViewTreeObserver_GlobalLayout;
private void ViewTreeObserver_GlobalLayout(object sender, EventArgs e)
{
_progressBar.ViewTreeObserver.GlobalLayout -= ViewTreeObserver_GlobalLayout;
SetProgressTextPosition();
}
and then I just calculate the current progress and SetX
accordinly.
//_progressBar = FindViewById<Android.Widget.ProgressBar>(Resource.Id.progressBar);
//_currentProgressStep = FindViewById<TextView>(Resource.Id.currentProgressStep);
private void SetProgressTextPosition()
{
if (!TotalStepCount.HasValue || !CurrentStep.HasValue)
{
return;
}
if (CurrentStep.Value > TotalStepCount.Value)
{
throw new ArgumentOutOfRangeException($"Please ensure that the current step does not exceed the total step amount.");
}
_currentProgressStep.Text = $"{CurrentStep.Value} / {TotalStepCount.Value}";
float startPosition = _progressBar.GetX();
float totalWidth = startPosition + _progressBar.Width;
float stepSize = totalWidth / TotalStepCount.Value;
float currentPosition = stepSize * CurrentStep.Value;
_currentProgressStep.SetX(currentPosition - _currentProgressStep.Width);
}
来源:https://stackoverflow.com/questions/60111092/mvvmcross-native-android-progressbar-move-element-with-the-current-progress