多くのアプリに表示されているのと同じ機能を追加しようとしています。画面の上部領域は、スクロールされたコンテンツに応じて縮小および拡大します。
このために、 the CheeseSquare sample に示すように、Googleのデザインライブラリを使用します。
NestedScrollViewのコンテンツの量に関係なく、コンテンツの最後のビューの下までスクロールして、アクションバーの最終的な状態を確認できます。
要するに、これは一番下までスクロールしたときに表示されるものです(CheeseSquareサンプルの変更されたコンテンツ):
これは私が一番下にスクロールするときに持っているものです(連絡先アプリから取得):
また、 ThreePhasesBottomSheet のバグを修正しようとしていますピーク状態。再現するには、水平方向にスクロールを開始し(この方法では何もしないので何もしません)、次に垂直方向にスクロールすると、ボトムシートのコンテンツのスクロールが何らかの形でトリガーされます。
したがって、「translationView()」メソッドでのスクロールを無効にする必要があります。「translation
これは、通常の使用法を使用した場合の動作です:
そして、これはスクロールをブロックしないというバグでどのように動作するかです:
「 layout_scrollFlags 」フラグを使用して、高さをwrap_contentに変更し、clipToPaddingを削除しようとしました。およびfitsSystemWindows属性。
サンプルXMLファイルは次のとおりです。多数の代わりに1つのcardViewのみを含めるように変更しました。
<Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="@dimen/detail_backdrop_height"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
Android:fitsSystemWindows="true">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
Android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
Android:id="@+id/backdrop"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scaleType="centerCrop"
Android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical"
Android:paddingTop="24dp">
<Android.support.v7.widget.CardView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="Info"
Android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="@string/cheese_ipsum" />
</LinearLayout>
</Android.support.v7.widget.CardView>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
<Android.support.design.widget.FloatingActionButton
Android:layout_height="wrap_content"
Android:layout_width="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
Android:src="@drawable/ic_discuss"
Android:layout_margin="@dimen/fab_margin"
Android:clickable="true"/>
</Android.support.design.widget.CoordinatorLayout>
私も次のコードを試しました:
((AppBarLayout.LayoutParams) collapsingToolbar.getLayoutParams()).setScrollFlags(0);
しかし、これは CheeseSquare の例でNestedScrollView自体のスクロールを許可し、 ThreePhasesBottomSheet サンプル.
下部に表示するコンテンツがなくなったときにスクロールを停止するにはどうすればよいですか?
さらに、いつでもNestedScrollViewのスクロールを無効にするために何ができますか( ThreePhasesBottomSheet サンプル)? 「setEnableScrolling(...)」のようなものですか?
NestedScrollViewを拡張し、ScrollingViewBehaviorからも拡張しようとしましたが、スクロールを無効にするためにできることを見つけることができませんでした。
変更することはおそらく非常に簡単なことですが、私は何を見つけることができません...
編集:必要に応じて、これは現在私がデザインおよびサポートライブラリに使用しているものです
compile 'com.Android.support:appcompat-v7:23.1.0'
compile 'com.Android.support:design:23.1.0'
編集:#2の場合、BottomSheetLayout.Javaファイル内から回避策を見つけました。変数「sheetViewOwnsTouch」に関連するすべてのものを、常に「false」に設定されているかのように無効にします。これにより、ボトムシートのタッチイベントを盗むことができます。ただし、これは単なる回避策であり、この場合のみです。また、他のビューで処理されるはずのタッチイベントも発生します。プログラムでスクロールをブロックする方法と、コンテンツを表示するのに十分なスペースの他の場合でも、私はまだ知りたいと思っています。
下部に表示するコンテンツが他にない場合、スクロールを停止するにはどうすればよいですか?
まず、以下でコメントしたように、あなたが質問で言ったスクロールはNestedScrollView
のものではありません。 CollapsingToolbarLayout
に属します。 NestedScrollView
のスクロールイベントは、CollapsingToolbarLayout
が完全に折りたたまれたときにのみ発生します。もちろん、中にコンテンツがなくなるとスクロールが停止します(下端に到達)。 CollapsingToolbarLayout
の場合、ツールバーのlayout_heightに折りたたまれます(xmlファイルのように、"?attr/actionBarSize"
)。次の画像は、ツールバーである赤い長方形に注意することを示しています(背景を設定します)
したがって、#1の解決策を得るには、NestedScrollView
の高さを計算する必要があります。それが画面の高さよりも小さい場合は、ツールバーの高さを修正します。
つまり、activity_detail.xml
次のように:
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="@dimen/detail_backdrop_height"
Android:fitsSystemWindows="true"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
Android:id="@+id/backdrop"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="false"
Android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
Android:id="@+id/linearLayout1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.v7.widget.CardView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="Info"
Android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="@string/cheese_ipsum" />
</LinearLayout>
</Android.support.v7.widget.CardView>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
</Android.support.design.widget.CoordinatorLayout>
そしてCheeseDetailActivity.Java:
public class CheeseDetailActivity extends AppCompatActivity {
public static final String EXTRA_NAME = "cheese_name";
private final Context mContext = this;
private int screenHeight;
private int linearLayoutHeight;
private int toolbarHeight_org;
private int toolbarHeight;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent intent = getIntent();
final String cheeseName = intent.getStringExtra(EXTRA_NAME);
screenHeight = getScreenHeight(this);
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
final int colorPrimary = typedValue.data;
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar);
final CoordinatorLayout.LayoutParams appbarLayoutParams = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();
final ViewGroup.LayoutParams toolbarLayoutParams = toolbar.getLayoutParams();
if (toolbarLayoutParams != null) {
toolbarHeight_org = toolbarLayoutParams.height;
toolbarHeight = toolbarLayoutParams.height;
}
final CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(cheeseName);
collapsingToolbar.setContentScrimColor(colorPrimary);
collapsingToolbar.setExpandedTitleTextAppearance(R.style.ExpandedTitleTextAppearance);
//collapsingToolbar.setCollapsedTitleTextAppearance(R.style.CollapsedTitleTextAppearance);
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout1);
ViewTreeObserver observer = linearLayout.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
linearLayoutHeight = linearLayout.getHeight();
if (linearLayoutHeight + toolbarHeight < screenHeight) {
if (toolbarLayoutParams != null) {
toolbarLayoutParams.height = screenHeight - linearLayoutHeight - 20;
if (toolbarLayoutParams.height < toolbarHeight_org) {
toolbarLayoutParams.height = toolbarHeight_org;
}
int extended_text_size = (int) getResources().getDimension(R.dimen.expanded_text_size);
if (appbarLayoutParams.height - toolbarLayoutParams.height <= extended_text_size) {
int value = appbarLayoutParams.height - toolbarLayoutParams.height;
if (value < 0) {
appbarLayoutParams.height = toolbarLayoutParams.height - value + extended_text_size * 3;
} else {
appbarLayoutParams.height = toolbarLayoutParams.height + extended_text_size * 3;
}
if (appbarLayoutParams.height >= screenHeight) {
appbarLayoutParams.height = screenHeight;
}
}
// collapsingToolbar.setContentScrimColor(getResources().getColor(Android.R.color.transparent));
if (toolbarLayoutParams.height > toolbarHeight_org) {
collapsingToolbar.setContentScrimColor(ContextCompat.getColor(mContext, Android.R.color.transparent));
}
}
}
// Removes the listener if possible
ViewTreeObserver viewTreeObserver = linearLayout.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
});
loadBackdrop();
appbar.setExpanded(true);
}
private int getScreenHeight(Context context) {
int measuredHeight;
Point size = new Point();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
wm.getDefaultDisplay().getSize(size);
measuredHeight = size.y;
} else {
Display d = wm.getDefaultDisplay();
measuredHeight = d.getHeight();
}
return measuredHeight;
}
private void loadBackdrop() {
final ImageView imageView = (ImageView) findViewById(R.id.backdrop);
Glide.with(this).load(Cheeses.getRandomCheeseDrawable()).centerCrop().into(imageView);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sample_actions, menu);
return true;
}
}
結果は次のとおりです。
Cheesesquareサンプルを使用して、このプロジェクトをカスタマイズし、 My GitHub にアップロードしました。それでもまだいくつかの問題があることに同意しますが、少なくとも最初の問題の解決策になる可能性があります。
ご覧ください。それが役に立てば幸い!
スクロールを無効にするには、NestedScrollViewとLinearLayoutの子の高さの両方を「wrap_content」に設定するだけです。
それはあなたが望むように完全には機能しませんが、少なくともコンテンツが画面に完全に収まる場合はスクロールできません。
連絡先アプリの例について言えば、CoordinatorLayoutなどの付属物を使用していないようです。
この動作は次の方法で実行できます。
<ScrollView
Android:id="@+id/scroll_adinfo"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical">
<ImageView
Android:id="@+id/image"
Android:layout_width="match_parent"
Android:layout_height="@dimen/image_height"
Android:src="@mipmap/ic_launcher"/>
<LinearLayout
Android:id="@+id/layout_content"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:paddingTop="@dimen/image_height">
<!-- YOUR CONTENT HERE -->
</LinearLayout>
</FrameLayout>
</ScrollView>
そして、あなたのコードでは、スクロールで画像を移動します:
final ImageView image = (ImageView) findViewById(R.id.image);
((ScrollView) rootView.findViewById(R.id.scroll_adinfo)).getViewTreeObserver().addOnScrollChangedListener(
new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
int scrollY = ((ScrollView) rootView.findViewById(R.id.scroll_adinfo)).getScrollY();
image.setY(scrollY / 2);
}
});
私は自分のプロジェクトの1つからそれを抽出して編集したので、何かを見逃すことがあります。