web-dev-qa-db-ja.com

Android CollapsesingToolbarLayout with custom View

Cheesesquareサンプルプロジェクトに従って、新しいデザインマテリアルライブラリを理解しています。

CollapsingToolbarLayoutウィジェットによって提供される単純なタイトルの代わりに、ImageView、タイトル、およびサブタイトルでカスタムビュー(Telegramなど)を使用する方法があるかどうか疑問に思っています。

ありがとう。

24
CeccoCQ

私は同じ問題を抱えていて、解決策を見つけるのに何時間も費やしました。私の解決策は、折りたたみビュー(ImageViewとTextView)をCollapsingToolbarLayout内に追加してから、コードで遷移を処理することでした。このように、CollapsingToolbarLayoutから拡張するよりも柔軟でシンプルです。

最初に、視差プロパティを使用してCollapsingToolbarLayout内にビューを追加する必要があります。

        <ImageView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:paddingTop:"80dp"
            Android:src="@drawable/icon"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here

次に、OnOffsetchangeListnerを使用してビューのスケーリングを設定します。

  private static final float SCALE_MINIMUM=0.5f;
  appBarLayout.setOnWorkingOffsetChange(new  ControllableAppBarLayout.OnWorkingOffsetChange() {
        @Override
        public void onOffsetChange(int offSet, float collapseDistance) {
            imageView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM));
            imageView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM));

            textView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM));
            textView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM));

            // You can also setTransitionY/X, setAlpha, setColor etc.
        }
    });

どういうわけか、デフォルトのoffsetChangedListenerが適切に機能しなかったので(おそらくデフォルトのリスナーでまず試してみるべきでしょう)、 https:// GistのControllableAppBarLayoutを使用しました.github.com/blipinsk/3f8fb37209de6d3eea99 および以下を追加しました:

private OnWorkingOffsetChange onWorkingOffsetChange;

@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
    if (!isInEditMode()) {
        onWorkingOffsetChange.onOffsetChange(i, (float) i / appBarLayout.getTotalScrollRange());
    }
}

public void setOnWorkingOffsetChange(OnWorkingOffsetChange listener) {
    this.onWorkingOffsetChange = listener;
}

public interface OnWorkingOffsetChange {
    void onOffsetChange(int offSet, float collapseDistance);
}

唯一の問題は、CollapsingToolbarLayoutapp:contentScrim="#00000000"(透明)を設定する必要があるため、ツールバーが折りたたまれたときにビューが表示されることです。折り畳み背景効果が本当に必要な場合は、OffsetChangeListenerで背景ImageViewのアルファを設定することでこれを「偽造」できると確信しています。 ;)

20
Ciron

ウィジェット自体からは、カスタムビューをツールバーに追加できるように、これを直接有効にする方法はないようです。

ただし、できることは、CollapsingToolbarLayout.classのソースを開き、CollapsingTextHelper.classを使用してタイトルを設定する方法を確認することです。 CollapsingToolbarLayoutから拡張することにより、独自のウィジェットを作成することができます。

これらのリンクは、カスタムコンポーネント/ビューをまだ作成していない場合、カスタムコンポーネント/ビューの作成に役立ちます。 カスタムビューカスタムコンポーネント

私はまだこれを試していませんが、実際にあなたが探しているのと同様の解決策を達成しようと考えていたものです。これまでの手順:

  1. attrs.xmlで字幕設定のカスタム属性を作成します
  2. 元の名前を拡張して、独自のMyCollapsingToolbarLayoutを作成します。
  3. コンストラクターでsuperを呼び出して、元のコンポーネントがそのまま残るようにしてください。
  4. 新しいsubtitleTextHelperをコンポーネントに追加して、CollapsingTextHelperを作成します。
  5. onDrawをオーバーライドして、実際に字幕を描画します。
  6. CollapingsToolbarLayoutを含むレイアウトを字幕属性(デフォルトのスタイル設定など、固定字幕テキスト)で更新します。
  7. Activityを含むCollapsingToolbarの変更を適用します。 (CollapsingToolbarlayoutMyCollapingsToolbarLayoutに変換し、字幕、追加のカスタム設定などを設定します)。
  8. クロスフィンガー、テスト。

今すぐ見に行きます。

2
StingRay5

クリストファーの答えを少し編集して、カスタムビューを折りたたみ時に消えないようにする方法を示します。

最初に、視差プロパティを使用してCollapsingToolbarLayout内にビューを追加する必要があります。

        <ImageView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:paddingTop:"80dp"
            Android:src="@drawable/icon"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here

代わりに、カスタムビューをプログラムで追加すると、折りたたみ時に消えることはありません。たとえば、タイトルとサブタイトルを含むビューは次のとおりです。

    final FrameLayout frameLayout = new FrameLayout(mActivity);
    FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT);
    frameLayout.setLayoutParams(frameLayoutParams);


    // Create new LinearLayout
    final LinearLayout linearLayout = new LinearLayout(mActivity);
    frameLayoutParams =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, dpToPixels(78));
    frameLayoutParams.gravity = Gravity.BOTTOM;
    linearLayout.setLayoutParams(frameLayoutParams);
    linearLayout.setOrientation(LinearLayout.VERTICAL);


    // Add textviews
    final TextView textView1 = new TextView(mActivity);
    LinearLayout.LayoutParams linearLayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    frameLayoutParams.gravity = Gravity.BOTTOM;
    textView1.setLayoutParams(linearLayoutParams);
    textView1.setText("Title");
    textView1.setTextColor(ContextCompat.getColor(mActivity, R.color.colorWhite));
    textView1.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40);
    linearLayout.addView(textView1);


    final TextView textView2 = new TextView(mActivity);
    linearLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    textView2.setLayoutParams(linearLayoutParams);
    textView2.setText("Subtitle");
    textView2.setTextColor(ContextCompat.getColor(mActivity, R.color.colorWhite));
    textView2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
    linearLayout.addView(textView2);

    frameLayout.addView(linearLayout);


    collapsingToolbar.addView(frameLayout);
    final float SCALE_MIN=0.4f;
    AppBarLayout appBarLayout = (AppBarLayout) mActivity.findViewById(R.id.appBarLayout);
    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int offSet) {
            float collapsedRatio = (float) offSet / appBarLayout.getTotalScrollRange();
            linearLayout.setScaleX(1 + (collapsedRatio * SCALE_MIN));
            linearLayout.setScaleY(1 + (collapsedRatio * SCALE_MIN));
            FrameLayout.LayoutParams frameLayoutParams =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, dpToPixels(78));
            frameLayoutParams.gravity = Gravity.BOTTOM;
            frameLayoutParams.setMargins(Math.round(dpToPixels(48) * (1+collapsedRatio)), 0, 0, Math.round(dpToPixels(15) * collapsedRatio));
            linearLayout.setLayoutParams(frameLayoutParams);
            // You can also setTransitionY/X, setAlpha, setColor etc.
        }
    });

/////

float lastCollapsedRatio = -2;

////

private int dpToPixels(int padding_in_dp){
    final float scale = getResources().getDisplayMetrics().density;
    int padding_in_px = (int) (padding_in_dp * scale + 0.5f);
    return padding_in_px;
}
2
luca992