ドキュメントを検索しましたが、これだけが見つかりました: リンク 。バーを半透明にするために使用されるものはどれですか。私がやろうとしているのは、ステータスバーを完全に透明にして(下図のように)後方互換性を持たせることです。 APK <19の場合:
私のstyles.xml:
<resources xmlns:tools="http://schemas.Android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="Android:actionBarStyle">@style/ThemeActionBar</item>
<item name="Android:windowActionBarOverlay">true</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/ThemeActionBar</item>
<item name="windowActionBarOverlay">true</item>
</style>
<style name="ThemeActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="Android:background"> @null </item>
<!-- Support library compatibility -->
<item name="background">@null</item>
<item name="Android:displayOptions"> showHome | useLogo</item>
<item name="displayOptions">showHome|useLogo</item>
</style>
</resources>
私ができたこと
あなたがする必要があるのはあなたのテーマでこれらのプロパティを設定することです:
<item name="Android:windowTranslucentStatus">true</item>
<item name="Android:windowTranslucentNavigation">true</item>
透明なステータスバーを表示したいアクティビティ/コンテナレイアウトには、このプロパティセットが必要です。
Android:fitsSystemWindows="true"
KitKatより前のバージョンでは、これを確実に実行することは一般的に不可能で、実行できるように見えます が、奇妙なコードがそれを可能にします 。
編集:私はこのライブラリをお勧めします: https://github.com/jgilfelt/SystemBarTint 前ロリポップステータスバーの色制御の多くの。
私はLollipopのためにステータスバーとナビゲーションバーに配置された半透明または色を完全に無効にするための答えがウィンドウ上でこのフラグをセットすることであることを多くの熟考の後に学びました:
// In Activity's onCreate() for instance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
他のテーマは必要ありません、それはこのようなものを生み出します:
このコード行をメインのJavaファイルに追加するだけです。
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);
外部ライブラリ StatusBarUtil を使うことができます。
あなたのモジュールレベルに追加build.gradle
:
compile 'com.jaeger.statusbarutil:library:1.4.0'
次に、アクティビティに対して次のutilを使用して、ステータスバーを透明にすることができます。
StatusBarUtil.setTransparent(Activity activity)
例:
Android KitKat以上で動作します(ステータスバーを透過させたいがNavigationBarを操作したくない人は、これらすべての答えがNavigationBarも透過します)。
それを達成するための最も簡単な方法:
これらの3行のコードをstyles.xml (v19)
- >に入れることができないのなら(v19)、デフォルトのstyles.xml
に書いてから alt+enter 自動的に作成するには:
<item name="Android:windowFullscreen">false</item>
<item name="Android:windowContentOverlay">@null</item>
<item name="Android:fitsSystemWindows">false</item>
そして今、あなたのMainActivity
クラスに行き、このメソッドをクラスのonCreateから外してください:
public static void setWindowFlag(Activity activity, final int bits, boolean on) {
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
次に、このコードをActivityのonCreate
メソッドに配置します。
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}
if (Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
//make fully Android Transparent Status bar
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
それでおしまい!
ステータスバーの下にレイアウトを描画するには
values/styles.xml
<item name="Android:windowTranslucentStatus">true</item>
values-v21/styles.xml
<item name="Android:windowDrawsSystemBarBackgrounds">true</item>
<item name="Android:statusBarColor">@color/colorPrimaryDark</item>
すでにfitsSystemWindowsパラメータを処理するCoordinatorLayout/DrawerLayoutを使用するか、次のように独自のレイアウトを作成します。
public class FitsSystemWindowConstraintLayout extends ConstraintLayout {
private Drawable mStatusBarBackground;
private boolean mDrawStatusBarBackground;
private WindowInsetsCompat mLastInsets;
private Map<View, int[]> childsMargins = new HashMap<>();
public FitsSystemWindowConstraintLayout(Context context) {
this(context, null);
}
public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (ViewCompat.getFitsSystemWindows(this)) {
ViewCompat.setOnApplyWindowInsetsListener(this, new Android.support.v4.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
FitsSystemWindowConstraintLayout layout = (FitsSystemWindowConstraintLayout) view;
layout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
return insets.consumeSystemWindowInsets();
}
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
TypedArray typedArray = context.obtainStyledAttributes(new int[]{Android.R.attr.colorPrimaryDark});
try {
mStatusBarBackground = typedArray.getDrawable(0);
} finally {
typedArray.recycle();
}
} else {
mStatusBarBackground = null;
}
}
public void setChildInsets(WindowInsetsCompat insets, boolean draw) {
mLastInsets = insets;
mDrawStatusBarBackground = draw;
setWillNotDraw(!draw && getBackground() == null);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
if (ViewCompat.getFitsSystemWindows(this)) {
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) child.getLayoutParams();
if (ViewCompat.getFitsSystemWindows(child)) {
ViewCompat.dispatchApplyWindowInsets(child, insets);
} else {
int[] childMargins = childsMargins.get(child);
if (childMargins == null) {
childMargins = new int[]{layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin};
childsMargins.put(child, childMargins);
}
if (layoutParams.leftToLeft == LayoutParams.PARENT_ID) {
layoutParams.leftMargin = childMargins[0] + insets.getSystemWindowInsetLeft();
}
if (layoutParams.topToTop == LayoutParams.PARENT_ID) {
layoutParams.topMargin = childMargins[1] + insets.getSystemWindowInsetTop();
}
if (layoutParams.rightToRight == LayoutParams.PARENT_ID) {
layoutParams.rightMargin = childMargins[2] + insets.getSystemWindowInsetRight();
}
if (layoutParams.bottomToBottom == LayoutParams.PARENT_ID) {
layoutParams.bottomMargin = childMargins[3] + insets.getSystemWindowInsetBottom();
}
}
}
}
}
requestLayout();
}
public void setStatusBarBackground(Drawable bg) {
mStatusBarBackground = bg;
invalidate();
}
public Drawable getStatusBarBackgroundDrawable() {
return mStatusBarBackground;
}
public void setStatusBarBackground(int resId) {
mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null;
invalidate();
}
public void setStatusBarBackgroundColor(@ColorInt int color) {
mStatusBarBackground = new ColorDrawable(color);
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDrawStatusBarBackground && mStatusBarBackground != null) {
int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
if (inset > 0) {
mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
mStatusBarBackground.draw(canvas);
}
}
}
}
main_activity.xml
<FitsSystemWindowConstraintLayout 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:fitsSystemWindows="true">
<ImageView
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:fitsSystemWindows="true"
Android:scaleType="centerCrop"
Android:src="@drawable/toolbar_background"
app:layout_constraintBottom_toBottomOf="@id/toolbar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="0dp"
Android:layout_height="?attr/actionBarSize"
Android:background="@Android:color/transparent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:text="Content"
Android:textSize="48sp" />
</LinearLayout>
</FitsSystemWindowConstraintLayout>
結果:
一番上のレイアウトにAndroid:fitsSystemWindows="false"
を使う
完全に透明なステータスバーとナビゲーションバー
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
transparentStatusAndNavigation();
}
private void transparentStatusAndNavigation() {
//make full transparent statusBar
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
}
if (Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
}
}
private void setWindowFlag(final int bits, boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
これがトリックをするkotlinの拡張です:
fun Activity.setTransparentStatusBar() {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
window.statusBarColor = Color.TRANSPARENT
}
}
XMLでこのコードを使用すると、アクティビティのタイムバーを見ることができます。
<Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
つのステップがあります:
1)このコードセグメントを@OnCreateメソッドに使用するだけです
@OnCreate{
// FullScreen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
fragmentで作業している場合、このコードセグメントをアクティビティの@OnCreateメソッドに配置する必要があります。
2) /res/values-v21/styles.xmlで透明度も設定してください:
<item name="Android:statusBarColor">@Android:color/transparent</item>
または、プログラムで透明度を設定できます。
getWindow().setStatusBarColor(Color.TRANSPARENT);
)とにかくstyles.xmlにコードセグメントを追加する必要があります
<item name="Android:windowTranslucentStatus">true</item>
注:このメソッドは、API 21以降でのみ機能します。
Android:fitsSystemWindows="true"
はv21でのみ動作します。テーマxml、またはLinearLayout
のような親レイアウト、またはCoordinateLayout
に設定できます。 v21より下の場合、このフラグを追加できませんでした。必要に応じて、別のstyle.xml
ファイルを使用して別のvaluesフォルダを作成してください。
これは私のために働いた:
<item name="Android:statusBarColor">@Android:color/transparent</item>
<item name="Android:navigationBarColor">@Android:color/transparent</item>
<item name="Android:windowTranslucentStatus">false</item>
<item name="Android:windowTranslucentNavigation">false</item>
あなたはそれを試すことができます。
private static void setStatusBarTransparent(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
アバターとテキストを使って私の例を見ることもできます
私の 中位の記事を読む
それで私はそれがどのように機能するかを説明することができます。カスタムビューを実装したAppBarLayout.OnOffsetChangedListenerを作成しました。内部HeadCollapsingカスタムビュー私はAppBarLayoutでテキストと画像ビューを作りました。
class HeadCollapsing(context: Context, attrs: AttributeSet?) :
FrameLayout(context, attrs), AppBarLayout.OnOffsetChangedListener {
private fun findViews() {
appBarLayout = findParentAppBarLayout()
avatarContainerView = findViewById(R.id.imgb_avatar_wrap)
titleToolbarText = findViewById<AppCompatTextView>(id)
}
private fun findParentAppBarLayout(): AppBarLayout {
val parent = this.parent
return parent as? AppBarLayout ?: if (parent.parent is AppBarLayout) {
parent.parent as AppBarLayout
} else {
throw IllegalStateException("Must be inside an AppBarLayout")
}
}
...
override fun onOffsetChanged(appBarLayout: AppBarLayout, offset:Int) {
...
//Calculate expanded percentage
val expandedPercentage = 1 - -offset / maxOffset
updateViews(expandedPercentage)
}
}
その後、計算された割合でビューを変更します。たとえば、テキストビューの変化は次のようになります。
when {
inversePercentage < ABROAD -> {
titleToolbarText?.visibility = View.VISIBLE
titleTolbarTextSingle?.visibility = View.INVISIBLE
}
inversePercentage > ABROAD -> {
titleToolbarText?.visibility = View.INVISIBLE
titleTolbarTextSingle?.visibility = View.VISIBLE
titleTolbarTextSingle?.let {
animateShowText(it)
}
}
}
画像の崩壊が必要なときに検出するには作成したペアオブジェクトをアニメートします
private var cashCollapseState: kotlin.Pair<Int, Int>? = null
状態あり:TO_EXPANDED_STATE、TO_COLLAPSED_STATE、WAIT_FOR_SWITCH、SWITCHED
companion object {
const val ABROAD = 0.95f
const val TO_EXPANDED_STATE = 0
const val TO_COLLAPSED_STATE = 1
const val WAIT_FOR_SWITCH = 0
const val SWITCHED = 1
}
その後、アバター交換状態のアニメーションを作成しました。
when {
cashCollapseState != null && cashCollapseState != state -> {
when (state.first) {
TO_EXPANDED_STATE -> {
// do calculates
}
TO_COLLAPSED_STATE -> {
ValueAnimator.ofFloat(avatarContainerView.translationX, translationX).apply {
addUpdateListener {
avatarContainerView.translationX = it.animatedValue as Float
}
duration = 350
(state.first == TO_COLLAPSED_STATE).apply {
if (this) interpolator = LinearInterpolator()
}
start()
}
//SWITCH STATE CASE
cashCollapseState = kotlin.Pair(state.first, SWITCHED)
}
else -> {
cashCollapseState = kotlin.Pair(state.first, WAIT_FOR_SWITCH)
}
setContentView()の前にこれらの行をアクティビティに追加します。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
これら2行をAppThemeに追加してください
<item name="Android:windowTranslucentStatus">true</item>
<item name="Android:windowTranslucentNavigation">true</item>
そして最後にあなたのminSdkVersionはb 19でなければなりません
minSdkVersion 19
必要なのはMainActivity.Java
に入ることだけです。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window g = getWindow();
g.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
setContentView(R.layout.activity_main);
}