私のアプリケーションでは、上部に何らかのアクションバーがあり、その下にリストビューがあるアクティビティがありました。私がしたいことは、リストで上にスクロールすることです。したがって、非表示になり、リストが下にスクロールされているときに、画面の上部の境界の上にあるようにリストで下にスクロールする必要がありますこの機能をどのように実現できますか?
GoogleはCoordinatorLayout
を使用してこれをサポートするようになりました。
<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.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways" />
<Android.support.design.widget.TabLayout
Android:id="@+id/tabs"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" />
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
Android:id="@+id/viewpager"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="end|bottom"
Android:layout_margin="@dimen/fab_margin"
Android:src="@drawable/ic_done" />
</Android.support.design.widget.CoordinatorLayout>
ここに文書化されています:https://developer.Android.com/reference/Android/support/design/widget/AppBarLayout.html =
https://github.com/umano/AndroidSlidingUpPanel
このリポジトリのコードを見てください。パネルを上にスライドさせると、ActionBarも上にスライドします。
デモから:
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
SlidingUpPanelLayout layout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
layout.setShadowDrawable(getResources().getDrawable(R.drawable.above_shadow));
layout.setAnchorPoint(0.3f);
layout.setPanelSlideListener(new PanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
Log.i(TAG, "onPanelSlide, offset " + slideOffset);
if (slideOffset < 0.2) {
if (getActionBar().isShowing()) {
getActionBar().hide();
}
} else {
if (!getActionBar().isShowing()) {
getActionBar().show();
}
}
}
@Override
public void onPanelExpanded(View panel) {
Log.i(TAG, "onPanelExpanded");
}
@Override
public void onPanelCollapsed(View panel) {
Log.i(TAG, "onPanelCollapsed");
}
@Override
public void onPanelAnchored(View panel) {
Log.i(TAG, "onPanelAnchored");
}
});
ここからサンプルをダウンロードしてください:
https://play.google.com/store/apps/details?id=com.sothree.umano
私は最近同じ機能を望んでいましたが、これは私にとって完璧に機能します:
ユーザーが上方向にスクロールすると、ユーザーに作業用の画面全体を提供するためにActionBarが非表示になります。
ユーザーが下にスクロールして手放すと、ActionBarが戻ります。
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
listView.setOnScrollListener(new OnScrollListener() {
int mLastFirstVisibleItem = 0;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) { }
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (view.getId() == listView.getId()) {
final int currentFirstVisibleItem = listView.getFirstVisiblePosition();
if (currentFirstVisibleItem > mLastFirstVisibleItem) {
// getSherlockActivity().getSupportActionBar().hide();
getSupportActionBar().hide();
} else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
// getSherlockActivity().getSupportActionBar().show();
getSupportActionBar().show();
}
mLastFirstVisibleItem = currentFirstVisibleItem;
}
}
});
this.mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
int mLastFirstVisibleItem = 0;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
final int currentFirstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
if (currentFirstVisibleItem > this.mLastFirstVisibleItem) {
MainActivity.this.getSupportActionBar().hide();
} else if (currentFirstVisibleItem < this.mLastFirstVisibleItem) {
MainActivity.this.getSupportActionBar().show();
}
this.mLastFirstVisibleItem = currentFirstVisibleItem;
}
});
もう助けが必要かどうか教えてください!
ActionBarを非表示/表示することにより、コンテンツレイアウトに使用可能なスペースが変更され、再レイアウトが発生するため、ちらつきが発生します。これにより、最初に表示されるアイテムの位置のインデックスも変更されます(mLastFirstVisibleItemおよびcurrentFirstVisibleItemをログアウトすることで確認できます)。
ActionBarにコンテンツレイアウトをオーバーレイさせることで、ちらつきに対処できます。アクションバーのオーバーレイモードを有効にするには、既存のアクションバーテーマを拡張するカスタムテーマを作成し、Android:windowActionBarOverlayプロパティをtrueに設定する必要があります。
これにより、ちらつきをなくすことができますが、アクションバーはリストビューのコンテンツをオーバーレイします。これに対する簡単な解決策は、リストビュー(またはルートレイアウト)の上部パディングをアクションバーの高さに設定することです。
<ListView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@Android:id/list"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingTop="?android:attr/actionBarSize" />
残念ながら、これは上部に一定のパディングをもたらします。このソリューションの改良点は、?android:attr/actionBarSizeの高さを持つヘッダービューをリストビューに追加することです(前に設定した上部のパディングを削除します)。
探しているものは Quick Return pattern と呼ばれ、アクションバーに適用されます。 Google IO 2014 アプリはまさにそれを使用します。自分のアプリの1つで使用しています。そのGoogleアプリの ソースコード を確認できます。 BaseActivity クラスでは、必要なものを入手し、コードを読んでその特定の機能のみを抽出します。コーディングをお楽しみください!:)
それは最善の解決策ではないと確信しています。しかし、私はまだ良いものを見つけていません。役に立てば幸いです。
static boolean scroll_down;
...
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (scroll_down) {
actionBar.hide();
} else {
actionBar.show();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 70) {
//scroll down
scroll_down = true;
} else if (dy < -5) {
//scroll up
scroll_down = false;
}
}
});
良いアイデアだと思います。
listView.setOnScrollListener(new OnScrollListener() {
int mLastFirstVisibleItem = 0;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_FLING:
if (view.getId()==lv_searchresult_results.getId()){
final int currentFirstVisibleItem=lv_searchresult_results.getFirstVisiblePosition();
if(currentFirstVisibleItem>mLastFirstVisibleItem){
ObjectAnimator.ofFloat(toolbar, "translationY", -toolbar.getHeight()).start();
else if(currentFirstVisibleItem<(mLastFirstVisibleItem)){
ObjectAnimator.ofFloat(toolbar, "translationY", 0).start();
}
mLastFirstVisibleItem= currentFirstVisibleItem;
}
if(lv_searchresult_results.getLastVisiblePosition() == myAdapter.getListMap().size()){
if(myAdapter.getListMap().size() < allRows&&!upLoading){
}
}
break;
case OnScrollListener.SCROLL_STATE_IDLE:
if (view.getFirstVisiblePosition()<=1){
ObjectAnimator.ofFloat(toolbar, "translationY", 0).start();
}
if(lv_searchresult_results.getLastVisiblePosition() == myAdapter.getListMap().size()){
if(myAdapter.getListMap().size() < allRows&&!upLoading){
}
}
break;
私はそれがうまくいくと思う.....
listView.setOnScrollListener(new OnScrollListener() {
int mLastFirstVisibleItem = listView.getLastVisiblePosition();
boolean isScrolling = false;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == 0)
isScrolling = false;
else if(scrollState == 1)
isScrolling = true;
else if(scrollState == 2)
isScrolling = true;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (view.getId() == myTeamListView.getId()) {
if(isScrolling) {
final int currentFirstVisibleItem = myTeamListView.getLastVisiblePosition();
if (currentFirstVisibleItem > mLastFirstVisibleItem) {
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
} else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
((AppCompatActivity)getActivity()).getSupportActionBar().show();
}
mLastFirstVisibleItem = currentFirstVisibleItem;
}
}
}
});
CoordinatorLayoutを使用している場合、ここにトリックがあります。
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways" />
app:layout_scrollFlags="scroll|enterAlways"
行を使用すると、ユーザーがリストを下にスクロールするとツールバーが画面からスクロールし、スクロールを開始するとすぐにツールバーが再び表示されます。