我一直在尝试使用 ConstraintLayout 实现一个显示进度数据的栏。问题是当指南位于栏太左或太右时,我的 TextView 就会超出布局范围。
我尝试将 TextView 的约束从连接到“@id/guideline”的连接更改为“parent”,并添加horizontalBias,但随后 TextView 的位置会变得不准确(稍微移到右侧/左侧)取决于黄色条的长度)
这是布局代码:
<android.support.constraint.ConstraintLayout
android:id="@+id/layoutConstraint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingLeft="16dp"
android:paddingTop="100dp"
android:paddingRight="16dp"
android:paddingBottom="16dp">
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".01" />
<TextView
android:id="@+id/textProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="12dp"
android:textColor="@color/black"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@id/guideline"
app:layout_constraintStart_toStartOf="@id/guideline"
app:layout_constraintTop_toTopOf="parent"
tools:text="current value" />
<View
android:id="@+id/layoutProgress"
android:layout_width="0dp"
android:layout_height="8dp"
android:background="@drawable/background_rounded_corner_light_grey"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textProgress" />
<View
android:id="@+id/currentProgress"
android:layout_width="0dp"
android:layout_height="8dp"
android:background="@drawable/background_rounded_corner_yellow"
app:layout_constraintEnd_toStartOf="@id/guideline"
app:layout_constraintStart_toStartOf="@id/layoutProgress"
app:layout_constraintTop_toBottomOf="@id/textProgress" />
</android.support.constraint.ConstraintLayout>
最佳答案
看起来您希望将文本“当前值”保持在进度条末尾的中心;但是,如果此位置导致文本在左侧或右侧被截断,则文本应与 ConstraintLayout
的一侧对齐,以使其保持完全可见。
您的 TextView
集中在您以编程方式定位在 0% 和 100% 之间的百分比准则(我假设是这样。)
我建议您将引用线更改为基于像素(dp 或 px)的引用线,并将您的 TextView
放置在新引用线的中心。计算一个新的范围,而不是从零到 100% 改变指导线位置:
范围下限 = 1/2 TextView
宽度加上任意边距。
范围上限 = ConstraintLayout
的宽度 - TextView
的 1/2 宽度减去任何边距。
边距将保持在范围的低端,而进度则落在低端的左侧。当进度超过低端时,引导线将向右移动进度条的当前位置 - 低端。随着进度继续达到 100%,该指南将停止在高端。
如果您想坚持使用百分比准则,请按照上面所述计算低端和高端。然后,您可以根据容器的宽度计算低百分比和高百分比。
这是一个简短的演示,它使用一个简单的进度 block :
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ConstraintLayout mLayout;
private View mProgress;
private int mProgressPosition;
private int mGuidelineMin;
private int mGuidelineMax;
private Guideline mGuideline;
private int mIncrement;
private Handler mHandler = new Handler();
private int mMargin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLayout = findViewById(R.id.layout);
mGuideline = findViewById(R.id.guideline);
mProgress = findViewById(R.id.progress);
mMargin = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 16,
getResources().getDisplayMetrics()
);
mLayout.post(new Runnable() {
private int mLoopCount = 100;
@Override
public void run() {
int textWidth = findViewById(R.id.textView).getWidth();
mGuidelineMin = textWidth / 2 + mMargin;
mGuidelineMax = mLayout.getWidth() - textWidth / 2 - mMargin;
mGuideline.setGuidelineBegin(mGuidelineMin);
mIncrement = (mLayout.getWidth() - mProgress.getWidth()) / mLoopCount;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mProgressPosition += mIncrement;
mProgress.setTranslationX(mProgressPosition);
int guidelinePosition =
Math.max(mGuidelineMin, mProgressPosition + mProgress.getWidth() / 2);
if (guidelinePosition > mGuidelineMax) {
guidelinePosition = mGuidelineMax;
}
mGuideline.setGuidelineBegin(guidelinePosition);
if (--mLoopCount > 0) {
mHandler.postDelayed(this, 100);
}
}
}, 100);
}
});
}
}
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/progress"
android:layout_width="15dp"
android:layout_height="15dp"
android:background="@android:color/holo_red_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.17" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Current value"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.07999998" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="140dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
关于android - 将 subview 保留在 ConstraintLayout 的布局内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53495457/