Android 在RecyclerView/ListView onScroll上隐藏操作栏
在我的应用程序中,我得到了一个活动,它的顶部有一些actionbar,下面是listview。我想做的是——将它与列表一起向上滚动,这样它就隐藏了,然后,当列表向下滚动时——它应该与列表一起向下滚动,就像它刚好在屏幕的上边框上一样。如何实现此功能?2015年6月3日更新: 谷歌现在使用Android 在RecyclerView/ListView onScroll上隐藏操作栏,android,android-listview,scroll,android-actionbar,vertical-scrolling,Android,Android Listview,Scroll,Android Actionbar,Vertical Scrolling,在我的应用程序中,我得到了一个活动,它的顶部有一些actionbar,下面是listview。我想做的是——将它与列表一起向上滚动,这样它就隐藏了,然后,当列表向下滚动时——它应该与列表一起向下滚动,就像它刚好在屏幕的上边框上一样。如何实现此功能?2015年6月3日更新: 谷歌现在使用协调器布局支持这一点 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/ap
协调器布局
支持这一点
<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>
此处记录:
原始答复:
与Google Play Music和Umano应用程序类似的示例:
请查看此存储库中的代码。向上滑动面板时,操作栏也向上滑动
演示中的:
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");
}
});
getWindow().requestFeature(Window.FEATURE\u ACTION\u BAR\u覆盖);
SlidengUppanellayout布局=(SlidengUppanellayout)findViewById(R.id.Slideng_布局);
layout.setShadowDrawable(getResources().getDrawable(R.drawable.over_shadow));
布局。设置锚点(0.3f);
layout.setPanelSlideListener(新的PanelSlideListener(){
@凌驾
公共空心面板幻灯片(视图面板、浮动幻灯片偏移){
Log.i(标签“onPanelSlide,offset”+slideOffset);
如果(滑动偏移<0.2){
if(getActionBar().isShowing()){
getActionBar().hide();
}
}否则{
如果(!getActionBar().isShowing()){
getActionBar().show();
}
}
}
@凌驾
已展开的公用面板(视图面板){
Log.i(标签“onPanelExpanded”);
}
@凌驾
公共空心面板已折叠(视图面板){
Log.i(标签“onPanelCollapsed”);
}
@凌驾
公共空心板(视图面板){
Log.i(标签“onPanelAnchored”);
}
});
在此处下载示例:
ListView-不带库:
我最近想要相同的功能,这对我来说非常适合:
当用户向上滚动时,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;
}
}
});
getWindow().requestFeature(Window.FEATURE\u ACTION\u BAR\u覆盖);
setOnScrollListener(新的OnScrollListener(){
int mLastFirstVisibleItem=0;
@凌驾
public void onScrollStateChanged(AbsListView视图,int scrollState){}
@凌驾
public void onScroll(AbsListView视图,int firstVisibleItem,int visibleItemCount,int totalItemCount){
if(view.getId()==listView.getId()){
final int currentFirstVisibleItem=listView.getFirstVisiblePosition();
如果(currentFirstVisibleItem>mLastFirstVisibleItem){
//getSherlockActivity().getSupportActionBar().hide();
getSupportActionBar().hide();
}else if(currentFirstVisibleItem
RecyclerView-无库
this.mRecyclerView.setOnScrollListener(新的RecyclerView.OnScrollListener(){
int mLastFirstVisibleItem=0;
@凌驾
CrollStateChanged上的公共无效(RecyclerView RecyclerView,int newState){
}
@凌驾
已填空的公共空间(RecyclerView RecyclerView、int dx、int dy){
super.onScrolled(recyclerView、dx、dy);
final int currentFirstVisibleItem=mLinearLayoutManager.findFirstVisibleItemPosition();
如果(currentFirstVisibleItem>this.mLastFirstVisibleItem){
MainActivity.this.getSupportActionBar().hide();
}else if(currentFirstVisibleItem
如果你还需要帮助,请告诉我 通过隐藏/显示操作栏,您会体验到闪烁,因为内容布局更改的可用空间会导致重新播放。这样,第一个可见项的位置索引也会发生变化(您可以通过注销mLastFirstVisibleItem和currentFirstVisibleItem来验证这一点)
您可以通过让操作栏覆盖您的内容布局来应对闪烁。要启用操作栏的覆盖模式,您需要创建一个扩展现有操作栏主题的自定义主题,并将android:windowActionBarOverlay属性设置为true
使用此选项可以消除闪烁,但操作栏将覆盖listview的内容。解决此问题的简单方法是将listview(或根布局)的顶部填充设置为操作栏的高度
<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(并删除前面设置的顶部填充)你正在寻找的被称为,应用于操作栏。应用程序使用它。我在我的一个应用程序中使用它,你可以检查谷歌应用程序的名称,看看他们是如何得到它的。该类就是你拥有所需内容的地方,阅读代码并提取特定功能。享受编码吧!:)我确信这不是最好的解决方案。但我还没有找到更好的。希望这会有帮助
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;
}
}
});
static boolean向下滚动;
...
mrecycleView.setOnScrollListener(新的RecycleView.OnScrollListener(){
@凌驾
公众的
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;
}
}
}
});
<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" />