Ответ 1
Есть два варианта: в каждом случае вы добавляете один атрибут к тегу <ProgressBar/>
. Это либо
android:translationZ="2dp"
или
android:elevation="2dp"
Уровень API должен быть >= 21.
У меня есть этот макет моей активности входа. Я хочу наложить progressBar
, как это можно сделать, используя FrameLayout
. Как это сделать, используя ConstraintLayout
?
<layout>
<data>
<variable
name="vm"
type="com.app.android.login.vm" />
</data>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context="com.app.android.login.LoginActivity"
tools:ignore="missingPrefix">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_view_margin_bottom_8dp">
<android.support.design.widget.TextInputLayout
android:id="@+id/til_login_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/default_view_margin_right_8dp"
android:layout_marginStart="@dimen/default_view_margin_left_8dp"
android:textColorHint="@color/colorSecondaryText"
app:hintTextAppearance="@style/AppTheme.InputLayoutStyle"
app:layout_constraintBottom_toTopOf="@+id/til_login_password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_email"
android:imeOptions="actionNext"
android:singleLine="true"
android:text="@={vm.emailField}"
android:textColor="@color/colorPrimaryText" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/til_login_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/default_view_margin_right_8dp"
android:layout_marginStart="@dimen/default_view_margin_left_8dp"
android:textColorHint="@color/colorSecondaryText"
app:hintTextAppearance="@style/AppTheme.InputLayoutStyle"
app:layout_constraintBottom_toTopOf="@+id/btn_login_login"
app:layout_constraintTop_toBottomOf="@+id/til_login_email"
app:layout_constraintVertical_chainStyle="packed">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_password"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:singleLine="true"
android:text="@={vm.passwordField}"
android:textColor="@color/colorPrimaryText" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/btn_login_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/default_view_margin_right_8dp"
android:layout_marginStart="@dimen/default_view_margin_left_8dp"
android:layout_marginTop="48dp"
android:onClick="@{vm::login}"
android:text="@string/login_btn_text"
android:textColor="@color/colorWhite"
app:layout_constraintBottom_toTopOf="@+id/textview_login_forgot_password"
app:layout_constraintTop_toBottomOf="@+id/til_login_password"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/textview_login_forgot_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/default_view_margin_right_8dp"
android:layout_marginStart="@dimen/default_view_margin_left_8dp"
android:layout_marginTop="36dp"
android:gravity="center"
android:text="@string/login_forgot_password"
app:layout_constraintBottom_toTopOf="@+id/btn_login_register"
app:layout_constraintTop_toBottomOf="@+id/btn_login_login"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="@+id/btn_login_register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/default_view_margin_right_8dp"
android:layout_marginStart="@dimen/default_view_margin_left_8dp"
android:text="@string/login_sign_up"
android:textColor="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{vm.progressVisibility}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
</layout>
Он выглядит следующим образом:
Я ищу решение, которое должно работать для уровня API 19+. Я не хочу добавлять больше иерархии в свой макет, обертывая Button
или progressBar
внутри ViewGroup
или так.
Есть два варианта: в каждом случае вы добавляете один атрибут к тегу <ProgressBar/>
. Это либо
android:translationZ="2dp"
или
android:elevation="2dp"
Уровень API должен быть >= 21.
Если вы хотите на 100% наложить целевой вид, ограничьте все стороны наложения на соответствующие стороны целевого представления и установите высоту и ширину накладываемого вида на 0dp
следующим образом:
<View
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@id/animation_view"
app:layout_constraintLeft_toLeftOf="@id/animation_view"
app:layout_constraintRight_toRightOf="@id/animation_view"
app:layout_constraintTop_toTopOf="@id/animation_view"/>
Вот рабочий пример. На следующем изображении красный рисунок помещается поверх изображения. XML следует за изображением.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/animation_view"
android:layout_width="250dp"
android:layout_height="250dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#AAFF0000"
app:layout_constraintBottom_toBottomOf="@id/animation_view"
app:layout_constraintLeft_toLeftOf="@id/animation_view"
app:layout_constraintRight_toRightOf="@id/animation_view"
app:layout_constraintTop_toTopOf="@id/animation_view" />
</android.support.constraint.ConstraintLayout>
Подробнее см. для ConstraintLayout
.
Установить высоту над ProgressBar 2dp
, похоже, будет работать.
android:elevation="2dp"
Вы также можете попробовать установить translationZ
, как предложено в , на аналогичный вопрос. Для меня это работает на эмуляторе, работающем с API 17, и индикатор выполнения отображается сверху, как и ожидалось. Если вы получите предупреждение, проверьте версию сборки
Я хочу предоставить вам альтернативу XML-решению.
Вы также можете добавить представление в свое корневое представление. (ConstraintLayout
)
ViewGroupOverlay
- дополнительный слой, который находится поверх ViewGroup ( "представление хоста" ), который вычерчивается после всего остального содержимого в этом представлении (включая дочерние группы представлений). Взаимодействие с слоем наложения выполняется путем добавления и удаления представлений и чертежей.
<android.support.constraint.ConstraintLayout
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/default_view_margin_bottom_8dp">
Если вы ссылаетесь на корень в коде, вы можете добавить свой ProgressBar
.
Что-то вроде этого:
rootLayout.overlay.add(ProgressBar(context).apply {
measure(View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY))
layout(0, 0, 100, 100)
})
Вы также можете узнать об этом ссылка для получения дополнительной информации.
И этот fooobar.com/questions/459125/... вопрос также может помочь.
Вы можете попробовать один из следующих вариантов: 1. Добавьте относительный макет вне вашего макета как здесь
<RelativeLayout
android:id="@+id/relativelayout_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="#aa000022" >
<ProgressBar
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateOnly="true" />
</RelativeLayout>
Еще один простой способ решить это - изменить Button
на View
, изменить фон и размер. Наложите его на TextView
для замены старого текста Button
и другого View
для кликабельного позже
Вот ваше решение API 19. Он помещает CircularProgressDrawable
в наложение поверх вашего ConstraintLayout
.
Это выглядит так:
Что вам нужно сделать:
Избавьтесь от XML ProgressBar
.
Дайте XML ConstraintLayout
идентификатор, например:
android:id="@+id/cl"
Добавьте этот код в свою MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
boolean toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ConstraintLayout cl = findViewById(R.id.cl);
cl.setOnClickListener(this);
}
@Override
public void onClick(final View view) {
toggle ^= true;
if (toggle) {
startProgress();
} else {
stopProgress();
}
}
void startProgress() {
final ConstraintLayout cl = findViewById(R.id.cl);
final CircularProgressDrawable progressDrawable = new CircularProgressDrawable(this);
progressDrawable.setColorSchemeColors(Color.MAGENTA);
progressDrawable.setCenterRadius(50f);
progressDrawable.setStrokeWidth(12f);
progressDrawable.setStrokeCap(Paint.Cap.BUTT);
cl.post(new Runnable() {
@Override
public void run() {
progressDrawable.setBounds(0, 0, cl.getWidth(), cl.getHeight());
cl.getOverlay().add(progressDrawable);
}
});
progressDrawable.start();
}
void stopProgress() {
final ConstraintLayout cl = findViewById(R.id.cl);
final CircularProgressDrawable progressDrawable = new CircularProgressDrawable(this);
progressDrawable.setColorSchemeColors(Color.MAGENTA);
progressDrawable.setCenterRadius(50f);
progressDrawable.setStrokeWidth(12f);
progressDrawable.setStrokeCap(Paint.Cap.BUTT);
cl.post(new Runnable() {
@Override
public void run() {
cl.getOverlay().clear();
}
});
progressDrawable.stop();
}
}
В моих наблюдениях Android "складывает" представления вдоль оси z в том порядке, в котором они отображаются в файле xml, так что представление в конце файла будет в верхней части оси z, а представление в начале файл будет внизу. Конечно, как только вы начнете устанавливать высоту, zTranslation и т.д., Порядок стеков оси z будет изменен...
поэтому перемещение объявления progressBar в конец ConstraintLayout должно привести к тому, что оно появится над другими представлениями, это сработало для меня.
Вы можете достичь своей цели, установив перевод Z
для вида.
Поместите этот метод в вспомогательный класс (например: UIUtils
) и используйте его для вашего представления:
/**
* Set the 'Z' translation for a view
*
* @param view {@link View} to set 'Z' translation for
* @param translationZ 'Z' translation as float
*/
public static void setTranslationZ(View view, float translationZ) {
ViewCompat.setTranslationZ(view, translationZ);
}
ИСПОЛЬЗОВАНИЕ:
UIUTils.setTranslationZ(YOUR_VIEW, 5);