web-dev-qa-db-ja.com

Lollipop以前のデバイスのツールバーに標高/影を追加する

Androidアプリを新しいマテリアルデザインに更新しましたが、ツールバーに影または標高を追加したかったのです。 images/9-patchesを介してそれを行う(ハッキング)方法はいくつかあるように見えますが、サポートライブラリを介して行うことができるかどうかは疑問です。 (CardViewが昇格できるように)

this 別の質問の答えによると、これはToolbarAppBarLayoutにラップすることで可能ですが、これはうまくいきません。

私のレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.AppBarLayout 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="wrap_content">
    <Android.support.v7.widget.Toolbar
            Android:id="@+id/Toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:minHeight="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</Android.support.design.widget.AppBarLayout>

また、XMLおよびコードを使用して昇格を設定しようとしましたが、それも機能しません。

助けていただければ幸いです!前もって感謝します。

更新:

私はツールバーレイアウトを他のレイアウトに含めるため、以下はメインレイアウトの1つです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
    <include
        layout="@layout/Toolbar" />
    <fragment
        class="OverAllField.XamarinAndroid.Fragments.Planning.PlanningFragment"
        Android:id="@+id/PlanningFragment"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1" />
</LinearLayout>
36
avb

Android 5.0以降の場合:AppBarLayoutはレイアウトに影を自動的に提供/提供します。 app:elevation="4dp"によってAppBarLayoutの標高を上げることもできます。

Pre-Lollipopの場合:次のリンクを使用できます。 https://github.com/vipulasri/Toolbar-Elevation-Pre-Lollipop

注:ツールバーは、Android:elevation="4dp"を使用して、その高度をサポートします


新しい更新:Appcompat v24.0.0では、setElevation()およびapp:elevationが廃止されているため、AppBarLayoutに昇格を設定できません。

すぐに高度を設定するには、stateListAnimatorプロパティを使用する必要があります。

注:Elevation Drawingの遅延を回避するために、StateListAnimator1msに期間を設定します。

appCompat v24.0.0でAppBarLayoutの標高の変更が遅れる

appbar_always_elevated.xml in animator-v21フォルダーresディレクトリ。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item>
    <objectAnimator Android:propertyName="elevation"
                    Android:valueTo="8dp" 
                    Android:valueType="floatType"
                    Android:duration="1"/>
</item>
</selector>

AppbarLayoutで:

<Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="300dp"
        Android:fitsSystemWindows="true"
        Android:stateListAnimator="@animator/appbar_always_elevated"
        Android:theme="@style/AppTheme.AppBarOverlay">

</Android.support.design.widget.AppBarLayout>
63
Vipul Asri

アクティビティレイアウト内でAppBarLayoutを使用してみてください。試してください:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <include
            layout="@layout/Toolbar" />
    </Android.support.design.widget.AppBarLayout>

    <fragment
        class="OverAllField.XamarinAndroid.Fragments.Planning.PlanningFragment"
        Android:id="@+id/PlanningFragment"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1" />
</LinearLayout>

Toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.Toolbar
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/Toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:minHeight="?attr/actionBarSize"
    Android:background="?attr/colorPrimary"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
7
Binoy Babu

ビルドファイルを使用します。


compile 'com.Android.support:cardview-v7:23.1.1'

このリンクを参照

xmlで呼び出すには:

app:cardElevation="8dp"
app:cardCornerRadius="8dp"
app:contentPadding="5dp"
2
Ankush.Rana

CollapsingToolbarLayoutToolbarがあり、ツールバーのようなViewがあり、上下に移動しますが、 https:// githubのようにNestedScrollViewの上にあります.com/k0shk0sh/CoordinatorLayoutExample 。多くのバリエーションを試しました。 NestedScrollViewで画面上に影がスクロールすることもあれば、透明度のないソリッドシャドウをツールバーが描くこともあれば、エイリアスがエイリアスされることもありました。とにかく、これが私の解決策です。

レイアウトがあるとします:

<Android.support.design.widget.CoordinatorLayout>
    <Android.support.design.widget.AppBarLayout>
         <Android.support.design.widget.CollapsingToolbarLayout>
             <Android.support.v7.widget.Toolbar>
                 <!-- Toolbar views if needed -->
             </Android.support.v7.widget.Toolbar>
        </Android.support.design.widget.CollapsingToolbarLayout>
    </Android.support.design.widget.AppBarLayout>

    <!-- Footer Toolbar views if needed -->

    <Android.support.v4.widget.NestedScrollView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout>
            <!-- Views -->
        </LinearLayout>

    </Android.support.v4.widget.NestedScrollView>

    <!-- Add this view. It draws a shadow and aligns top of NestedScrollView -->
    <!-- Set visibility to gone or visible -->
    <View
        Android:id="@+id/scroll_shadow"
        Android:layout_width="match_parent"
        Android:layout_height="4dp"
        Android:background="@drawable/shadow"
        Android:visibility="gone"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</Android.support.design.widget.CoordinatorLayout>

シャドウを追加します(drawable/shadow.xml):

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <gradient
        Android:angle="90"
        Android:endColor="#ffcccccc"
        Android:startColor="#00cccccc" />
</shape>

このメソッドを追加します。ここで、scrollShadowは「scroll_shadow」という名前のビューです。

private void setShadowVisibility(int visibility) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
        scrollShadow.setVisibility(visibility);
    }
}

必要に応じて操作します。 Lollipop以前のデバイスではグラデーションが表示され、Android 5.0+では通常の影が表示されます。

2
CoolMind

最良の解決策は、ツールバーの下にグラデーションシャドウビューを配置し、デバイスSDKに依存する可視性で操作することだと思います。

toolbar.xml

 <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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="wrap_content"
        Android:orientation="vertical">

        <Android.support.v7.widget.Toolbar xmlns:Android="http://schemas.Android.com/apk/res/Android"
            xmlns:app="http://schemas.Android.com/apk/res-auto"
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="@Android:color/white"
            Android:fitsSystemWindows="true"
            app:popupTheme="@style/AppTheme.PopupOverlay">

            <TextView
                Android:id="@+id/centerTitleToolbarTextView"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:gravity="center"
                Android:maxLines="1"
                Android:textColor="@color/color_toolbar"
                Android:textSize="@dimen/titleToolbar" />

        </Android.support.v7.widget.Toolbar>

        <View
            Android:id="@+id/shadow_view"
            Android:layout_width="match_parent"
            Android:visibility="gone"
            Android:layout_height="4dp"
            Android:background="@drawable/toolbar_shadow" />

    </LinearLayout>

toolbar_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <gradient
        Android:startColor="#c1c1c1"
        Android:centerColor="#e6e6e6"
        Android:endColor="#f1f1f1"
        Android:angle="270" />
</shape>

MainActivity.class

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
        findViewById(R.id.shadow_view).setVisibility(View.VISIBLE);
      }
1
Levon Petrosyan

私もこの問題で1日を失いましたが、ようやくそれを機能させる方法を見つけました。

/**
 * Controller for the toolbar which will take care of the drop down shadow also on pre-Lollipop devices.
 * <br/>
 * The controller also handles the status bar based on the state of the toolbar.
 * <p/>
 * Created by <b>Negru Ionut Valentin</b> on <b>20/1/2016</b>.
 */
public class ToolbarController {

    private boolean handleStatusBar = false;
    private boolean showTitle = true;

    /**
     * Call this method in onCreate() method of your Activity or in onCreateView() in Fragment
     *
     * @param view
     *         The view into which to look for the toolbar
     * @param activity
     *         The activity for which setup the toolbar
     *
     * @return The toolbar found and customized or {@code null}
     */
    public Toolbar initToolbar(View view, Activity activity) {
        Toolbar mToolbar = (Toolbar) view.findViewById(R.id.toolbar);

        // Valid and visible toolbar - otherwise ignore
        if (null != mToolbar && mToolbar.getVisibility() == View.VISIBLE) {

            int paddingLeft = mToolbar.getPaddingLeft();
            int paddingRight = mToolbar.getPaddingRight();
            int paddingBottom = mToolbar.getPaddingBottom();
            // Set the top padding of the toolbar to match the status bar height
            int paddingTop = new CynnyContextWrapper(activity).getStatusBarHeight();

            mToolbar.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);

            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Lollipop) {
                ViewParent parent = mToolbar.getParent();
                if (parent instanceof RelativeLayout) {
                    // Manually create the drop shadow
                    RelativeLayout.LayoutParams params =
                            new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                                            Metrics.convertDpToPixel(4, activity));

                    View dropShadow = new View(activity);
                    dropShadow.setBackgroundResource(R.drawable.toolbar_shadow);

                    params.addRule(RelativeLayout.BELOW, R.id.toolbar);

                    ((RelativeLayout) parent).addView(dropShadow, params);
                }
            }

            if (activity instanceof AppCompatActivity) {
                // Check if the Activity actually support ActionBar with Toolbar and set our custom Toolbar for it
                ((AppCompatActivity) activity).setSupportActionBar(mToolbar);

                // Get the actionbar from the activity
                ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();
                if (null != actionBar) {
                    // If the actionbar is valid, customize it
                    actionBar.setDisplayHomeAsUpEnabled(true);
                    actionBar.setHomeButtonEnabled(true);

                    actionBar.setDisplayShowTitleEnabled(this.showTitle);

                    mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_selector);
                }
            }

            if (this.handleStatusBar) {
                // For showing the status bar
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            }
        } else if (handleStatusBar) {
            // Force hide the status bar
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        }

        return mToolbar;
    }

    /**
     * Set the flag indicating if the controller should handle or not the status bar.
     *
     * @param handleStatusBar
     *         Flag which indicates if the initialization of the toolbar should also update
     *         the status bar state (if two calls are made for the init, the last one will
     *         be taken into consideration).
     *
     * @return The current toolbar controller.
     */
    public ToolbarController setHandleStatusBar(boolean handleStatusBar) {
        this.handleStatusBar = handleStatusBar;

        return this;
    }

    /**
     * Set the flag indicating if the toolbar should show or hide the title.
     *
     * @param showTitle
     *         Flag indicating if the toolbar should also show the title (the title can be changed after the toolbar
     *         initialization)
     *
     * @return The current toolbar controller.
     */
    public ToolbarController setShowTitle(boolean showTitle) {
        this.showTitle = showTitle;

        return this;
    }
}

アクティビティでは、次のようにonCreate()メソッドでこれを使用する必要があります。

// Create and customize the Toolbar controller
new ToolbarController().setHandleStatusBar(true).setShowTitle(true)
                                 .initToolbar(((ViewGroup) findViewById(Android.R.id.content)).getChildAt(0),
                                              this);

フラグメントでは、次のようにonCreateView()メソッドでこれを使用する必要があります。

new ToolbarController().setHandleStatusBar(false).setShowTitle(false).initToolbar(resultView, getActivity());

レイアウトにツールバーを追加し、Android:id="@id/toolbar"でidを設定することを忘れないでください。別のIDを使用する場合は、コントローラーをカスタマイズし、指定したIDを使用する別のセッターメソッドを追加できます。

2つのツールバーレイアウトが作成されています。

v21

    <!-- This is the new widget added in Lollipop - use with care -->
    <Android.support.v7.widget.Toolbar
            Android:id="@id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:minHeight="?attr/actionBarSize"
            Android:theme="@style/TitleToolbarTheme"
            Android:background="?android:attr/colorPrimary"
            Android:elevation="@dimen/toolbar_elevation"
            />
</merge>

その他

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:Android="http://schemas.Android.com/apk/res/Android"
        >

    <!-- This is the new widget added in Lollipop - use with care -->
    <Android.support.v7.widget.Toolbar
            Android:id="@id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:minHeight="?attr/actionBarSize"
            Android:theme="@style/TitleToolbarTheme"
            Android:background="?attr/colorPrimary"
            />

</merge>

私はそれらを使用するかもしれないレイアウトで使用します:

<include layout="@layout/toolbar" />

これが問題の解決に役立つことを願っています。また、これはさらに最適化できることに注意してください。しかし、それは私にとっては有効であり、この問題でもう時間を無駄にしたくありません。

0
Ionut Negru