Android之AppBarLayout实现悬停吸附伸缩效果

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

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

app:layout_behavior=“@string/appbar_scrolling_view_behavior” >

``

app:layout_behavior=“@string/appbar_scrolling_view_behavior” >

CollapsingToolbarLayout:


CollapsingToolbarLayout也是android.support:design包中的支持的控件,继承自FrameLayout.主要用于实现ToolBar的伸缩效果,而且必须为AppBarLayout的直接子View;

继承结构图如下:

java.lang.Object

↳ android.view.View

↳ android.view.ViewGroup

↳ android.widget.FrameLayout

↳ android.support.design.widget.CollapsingToolbarLayout

主要使用到的方法如下:

  • setCollapsedTitleGravity

void setCollapsedTitleGravity(int gravity)

设置折叠标题和垂直重力的水平对齐方式,当折叠边界中有额外空间超出标题本身所需的空间时,将使用该对齐方式

相关的XML属性:

CollapsingToolbarLayout_collapsedTitleGravity

2.setExpandedTitleGravity

void setExpandedTitleGravity(int gravity)

设置展开标题和垂直重力的水平对齐方式,当扩展边界中有额外空间超出标题本身所需的空间时,将使用该对齐方式。

相关的XML属性:

CollapsingToolbarLayout_expandedTitleGravity

3.setExpandedTitleTextColor

void setExpandedTitleTextColor(ColorStateList colors)

设置展开标题的文本颜色。

4.setCollapsedTitleTextColor

void setCollapsedTitleTextColor(ColorStateList colors)

设置折叠标题的文本颜色。

5.setCollapsedTitleTypeface

void setCollapsedTitleTypeface(字体字体)

设置用于折叠标题的字体。

5.setExpandedTitleMarginBottom

void setExpandedTitleMarginBottom(int margin)

以像素为单位设置底部展开的标题边距。

相关的XML属性:

CollapsingToolbarLayout_expandedTitleMarginBottom

  • 固定Toolbar

app:layout_collapseMode=“pin”

6.更多方法见文档

关于AppBarLayout的三剑客组合就介绍的差不多了,想进一步了解的可以去查阅官方文档,上面都给出了连接的.

特别说明:

三剑客配合使用,可以做出一些很炫酷的UI效果.

但是前提必须满足:AppbarLayout 要作为CoordinatorLayout 的直接子View,而CollapsingToolbarLayout 要作为AppbarLayout 的直接子View ,否则,上面展示的效果将实现不了.

AppbarLayout实例展示


1.仿 [开眼App]个人中心效果

  • .xml布局文件:
<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

xmlns:fresco=“http://schemas.android.com/apk/res-auto”

xmlns:imagetext=“http://schemas.android.com/apk/res-auto”

xmlns:app=“http://schemas.android.com/apk/res-auto”

android:orientation=“vertical”

android:background=“@color/colorWhite”

<android.support.design.widget.AppBarLayout

android:id=“@+id/center_appbar_layout”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

app:elevation=“0dp”

android:background=“@color/colorWhite”

android:fitsSystemWindows=“true”

<android.support.design.widget.CollapsingToolbarLayout

android:id=“@+id/collapsing_toobar”

android:layout_width=“match_parent”

android:layout_height=“260dp”

app:layout_scrollFlags=“scroll|exitUntilCollapsed”

app:contentScrim=“@color/colorGraylight”

fresco:expandedTitleTextAppearance=“@style/style_textsize1”

fresco:collapsedTitleTextAppearance=“@style/style_textsize”

fresco:collapsedTitleGravity=“left”

fresco:expandedTitleMarginTop=“185dp”

fresco:expandedTitleGravity=“left”

fresco:expandedTitleMarginStart=“30dp”

<FrameLayout

app:layout_scrollFlags=“scroll”

android:layout_width=“match_parent”

android:layout_height=“180dp”>

<com.facebook.drawee.view.SimpleDraweeView

android:id=“@+id/avatar_max”

android:layout_width=“match_parent”

android:layout_height=“170dp” />

<com.facebook.drawee.view.SimpleDraweeView

android:layout_marginLeft=“20dp”

android:layout_gravity=“bottom”

android:id=“@+id/avatar_min”

android:layout_width=“70dp”

android:layout_height=“70dp”

fresco:actualImageScaleType=“centerCrop”

fresco:placeholderImageScaleType=“centerCrop”

fresco:roundedCornerRadius=“50dp”

/>

<FrameLayout

android:layout_marginTop=“180dp”

app:layout_scrollFlags=“scroll”

android:layout_width=“match_parent”

android:layout_height=“50dp”

<Button

android:id=“@+id/edit_btn”

android:layout_width=“60dp”

android:layout_height=“20dp”

android:layout_marginRight=“20dp”

android:layout_gravity=“right|center_vertical”

android:background=“@drawable/login_btn”

android:gravity=“center”

android:text=“编辑资料”

android:textColor=“@color/colorBlacklight”

android:textSize=“10sp” />

<TextView

android:layout_marginTop=“230dp”

app:layout_scrollFlags=“scroll”

android:textSize=“10sp”

android:id=“@+id/date”

android:layout_marginLeft=“20dp”

android:text=“2018.07.08注册”

android:textColor=“@color/colorGraylight”

android:layout_width=“match_parent”

android:layout_height=“wrap_content” />

<android.support.v7.widget.Toolbar

android:id=“@+id/toolbar”

android:layout_width=“match_parent”

app:layout_collapseMode=“pin”

android:layout_height=“?attr/actionBarSize”

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

</android.support.design.widget.CollapsingToolbarLayout>

<LinearLayout

android:gravity=“center_vertical”

android:layout_marginTop=“20dp”

android:background=“@color/colorGrayalpha”

android:layout_width=“match_parent”

android:layout_height=“70dp”>

<openeyes.dr.openeyes.widget.CustomImageTextView

android:id=“@+id/works”

android:layout_marginLeft=“40dp”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

imagetext:image=“@drawable/works2”

imagetext:text=“@string/works”

imagetext:textColor=“@color/colorGraylight”

</openeyes.dr.openeyes.widget.CustomImageTextView>

<openeyes.dr.openeyes.widget.CustomImageTextView

android:id=“@+id/attention”

android:layout_marginLeft=“90dp”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

imagetext:image=“@drawable/attention6”

imagetext:text=“@string/attention”

imagetext:textColor=“@color/colorGraylight”

</openeyes.dr.openeyes.widget.CustomImageTextView>

<openeyes.dr.openeyes.widget.CustomImageTextView

android:id=“@+id/fans”

android:layout_marginLeft=“90dp”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

imagetext:image=“@drawable/works2”

imagetext:text=“@string/fans”

imagetext:textColor=“@color/colorGraylight”

</openeyes.dr.openeyes.widget.CustomImageTextView>

</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView

android:id=“@+id/recycle_state”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

app:layout_behavior=“@string/appbar_scrolling_view_behavior”

/>

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

  • java文件:

public class PersonPageActivity extends SwipeBackActivity {

@BindView(R.id.avatar_max)

SimpleDraweeView avatarBackground;

@BindView(R.id.avatar_min)

SimpleDraweeView avatarUser;

@BindView(R.id.date)

TextView registerDate;

@BindView(R.id.works)

CustomImageTextView works;

@BindView(R.id.attention)

CustomImageTextView attention;

@BindView(R.id.fans)

CustomImageTextView fans;

@BindView(R.id.center_appbar_layout)

AppBarLayout appBarLayout;

@BindView(R.id.collapsing_toobar)

CollapsingToolbarLayout collToobar;

@BindView(R.id.toolbar)

Toolbar toolbar;

@BindView(R.id.recycle_state)

RecyclerView recyclerView;

private SharedPreferences sharedPreferences = MyApplication.sharedPreferences;

private HistoryDB db;

private List details = null;

private DynamicStateRecyclerAdapter adapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_person_page);

ButterKnife.bind(this);

initView();

initData();

}

private void initData() {

db = new HistoryDB();

details= db.loadHistoryByUserId(sharedPreferences.getString(“userId”,“000”));

if (details==null||details.size()==0){

}else {

Collections.reverse(details);

adapter = new DynamicStateRecyclerAdapter(details,this);

LinearLayoutManager manager = new LinearLayoutManager(this);

manager.setOrientation(LinearLayoutManager.VERTICAL);

recyclerView.setLayoutManager(manager);

recyclerView.setAdapter(adapter);

recyclerView.setItemAnimator(new DefaultItemAnimator());//添加默认动画

//设置RecyclerView的item监听事件

setOnItemClickListener();

}

}

private void setOnItemClickListener() {

adapter.setOnItemClickListener(new DynamicStateRecyclerAdapter.OnItemClickListener() {

@Override

public void onItemClick(View itemview, DynamicStateRecyclerAdapter.MyViewHolder childview, int position) {

initVideoDetail( position);//初始化视频详情界面数据并实现跳转

}

});

}

/**

  • 初始化视频详情界面数据,跳转至视频详情界面

  • */

private void initVideoDetail(int position) {

Intent intent = new Intent(PersonPageActivity.this, VideoDetailActivity.class);

Bundle bundle = new Bundle();

bundle.putString(“title”,details.get(position).getTitle());//获取标题

bundle.putString(“time”, details.get(position).getDetail());

bundle.putString(“desc”, details.get(position).getDesc());//视频描述

bundle.putString(“blurred”, details.get(position).getBlurred());//模糊图片地址

bundle.putString(“feed”, details.get(position).getPhoto());//图片地址

bundle.putString(“video”, details.get(position).getVideo());//视频播放地址

bundle.putInt(“collect”, details.get(position).getCollect());//收藏量

bundle.putInt(“share”, details.get(position).getShare());//分享量

bundle.putInt(“reply”, details.get(position).getReply());//回复数量

intent.putExtras(bundle);

startActivity(intent);

}

private void initView() {

avatarBackground.setImageURI(Uri.parse(sharedPreferences.getString(“userIcon”,“”)));

avatarUser.setImageURI(Uri.parse(sharedPreferences.getString(“userIcon”,“”)));

toolbar.setTitle(sharedPreferences.getString(“userName”,“”));//设置标题

collToobar.setExpandedTitleColor(getResources().getColor(R.color.colorBlack));

setSupportActionBar(toolbar);

getSupportActionBar().setDisplayShowHomeEnabled(true);

toolbar.setNavigationIcon(R.drawable.back_black);

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

finish();

}

});

}

@OnClick(R.id.attention)

public void onClick(){

startActivity(new Intent(this,MyAttentionActivity.class));

}

}

效果展示:

#####开眼app个人中心

2.仿[开眼App]搜索悬停界面:

  • .xml布局文件:
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

xmlns:app=“http://schemas.android.com/apk/res-auto”

android:orientation=“vertical”>

<LinearLayout

android:layout_width=“match_parent”

android:layout_height=“50dp”>

<openeyes.dr.openeyes.widget.SearchEditText

android:id=“@+id/search_editext”

android:layout_marginLeft=“20dp”

android:background=“@drawable/shape_search”

android:layout_width=“300dp”

android:layout_height=“30dp”

android:paddingLeft=“15dp”

android:paddingRight=“15dp”

android:gravity=“start|center_vertical”

android:imeOptions=“actionSearch”

android:singleLine=“true”

android:hint=“搜索视频、作者、用户及标签”

android:textSize=“13sp”

/>

<TextView

android:id=“@+id/cancle_main”

android:textColor=“@color/colorBlacklight”

android:gravity=“center”

android:text=“取消”

android:layout_width=“match_parent”

android:layout_height=“match_parent” />

<FrameLayout

android:id=“@+id/history_fl”

android:visibility=“gone”

android:layout_width=“match_parent”

android:layout_height=“50dp”

<TextView

android:layout_gravity=“center_vertical”

android:layout_marginLeft=“20dp”

android:textSize=“20sp”

android:text=“搜索历史”

android:textColor=“@color/colorBlack”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content” />

<TextView

android:id=“@+id/delete_history”

android:layout_marginRight=“20dp”

android:layout_gravity=“center_vertical|right”

android:textColor=“@color/colorAniBtns”

android:gravity=“center”

android:text=“清空”

android:textSize=“13sp”

android:layout_width=“50dp”

android:layout_height=“wrap_content” />

<android.support.design.widget.CoordinatorLayout

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:orientation=“vertical”

android:background=“@color/colorWhite”

<android.support.design.widget.AppBarLayout

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:background=“@color/colorWhite”

<android.support.v7.widget.RecyclerView

android:id=“@+id/search_history_rv”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

app:layout_scrollFlags=“scroll”

</android.support.v7.widget.RecyclerView>

<TextView

android:layout_marginLeft=“20dp”

android:text=“热搜关键词”

android:textSize=“20sp”

android:textColor=“@color/colorBlack”

android:layout_width=“match_parent”

android:layout_height=“wrap_content” />

</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView

android:id=“@+id/hot_search_rv”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

app:layout_behavior=“@string/appbar_scrolling_view_behavior”

</android.support.v7.widget.RecyclerView>

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

  • java文件:

package openeyes.dr.openeyes.view.activity;

public class SearchActivity extends AppCompatActivity {

@BindView(R.id.search_editext)

SearchEditText searchEditText;

@BindView(R.id.cancle_main)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

【Android 详细知识点思维脑图(技能树)】

我个人是做Android开发,已经有十来年了,目前在某创业公司任职CTO兼系统架构师。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

最后,赠与大家一句话,共勉!

wNeRJSb-1711913865705)]
[外链图片转存中…(img-oHj4fqpV-1711913865706)]
[外链图片转存中…(img-e92AoiWC-1711913865706)]
[外链图片转存中…(img-9WQNUeah-1711913865706)]
[外链图片转存中…(img-EhTwuf4U-1711913865706)]
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-Imet9IoC-1711913865707)]

总结

【Android 详细知识点思维脑图(技能树)】

[外链图片转存中…(img-x8LbKhrV-1711913865707)]

我个人是做Android开发,已经有十来年了,目前在某创业公司任职CTO兼系统架构师。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-cZIIE9vX-1711913865707)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

最后,赠与大家一句话,共勉!

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android RecyclerView 实现滑动悬停是通过使用 ItemDecoration 来实现的。在 RecyclerView 中滑动悬停需要满足两个条件:一是要有一个能够进行悬停的 View,二是要能够动态地根据 RecyclerView 的滚动来改变悬停 View 的位置。 实现滑动悬停的步骤如下: 1. 首先,我们需要创建一个继承自 RecyclerView.ItemDecoration 的类,例如名为 StickyHeaderDecoration 的类,来实现悬停 View。 2. 在 StickyHeaderDecoration 类中,我们需要重写 getItemOffsets() 方法,该方法会在每次绘制 RecyclerView 的子项时被调用。在该方法中,我们可以根据子项的位置和需要悬停的条件来判断是否需要为该子项添加偏移量,从而实现悬停效果。 3. 接下来,在 RecyclerView 的 Adapter 类中,我们需要重写两个方法:getItemViewType() 和 onCreateHolder()。 4. 在 getItemViewType() 方法中,我们可以根据当前子项的位置来判断是否需要为该子项设置一种特殊的 ViewType,用于标识悬停 View。例如当子项为要悬停的位置时,我们可以返回一个特定的 ViewType 值。 5. 在 onCreateHolder() 方法中,我们需要根据 ViewType 的不同创建不同的 ViewHolder。例如当 ViewType 为悬停 View 的类型时,我们可以创建一个单独的 ViewHolder 类来确定悬停 View 的样式。 6. 最后,在 RecyclerView 的布局文件中,我们需要将 StickyHeaderDecoration 添加到 RecyclerView 中,并设置它的布局参数。 通过以上步骤,我们就可以实现滑动悬停效果了。当滚动 RecyclerView 时,悬停 View 会根据 RecyclerView 的滚动位置动态地改变自己的位置,从而实现滑动悬停效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值