Android 仿支付宝应用分类
2020-01-09 本文已影响0人
微笑中的你
仿支付宝的应用分类
CoordinatorLayout + AppBarLayout + TabLayout + RecyclerView(嵌套RecyclerView)
完整代码请看Demo
[Demo_Github] (https://github.com/lxfwelldone/Demo_ZFBApp.git)
录制的gif 太大了,超过10M不给上传。。。
就给图片吧
QQ20200109-182254@2x.png QQ20200109-182315@2x.png实现上述效果思路:
1、如何实现悬浮效果
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expanded="true"
app:elevation="0dp"
>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:text="顶部内容"
android:textSize="30sp"
android:gravity="center"
app:layout_scrollFlags="scroll"
/>
<!-- 悬浮菜单 -->
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_app_group"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#fff"
app:tabTextColor="#333"
app:tabSelectedTextColor="#f00"
app:tabIndicatorColor="#f00"
app:tabIndicatorFullWidth="false"
app:tabInlineLabel="false"
app:tabMode="scrollable"
app:tabRippleColor="#fff"
app:tabIndicatorHeight="1dp"
/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_all"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
// app:elevation="0dp" 去除AppBarLayout底部黑线
2、如何实现联动?
TabLayout 和 RecyclerView 监听点击事件和滚动事件
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (!isInit){
mAppBar.setExpanded(false, true); //点击时置顶bar
}
if (isInit) isInit = false;
//点击tab的时候,RecyclerView自动滑到该tab对应的item位置
int position = tab.getPosition();
if (!isScroll) {
// 有动画且滚动到该分组
mSmoothScroller.setTargetPosition(position);
mLinearLayoutManager.startSmoothScroll(mSmoothScroller);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
isScroll = false;
} else {
isScroll = true;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//滑动RecyclerView list的时候,根据最上面一个Item的position来切换tab
// mTabLayout.setScrollPosition(mLinearLayoutManager.findFirstVisibleItemPosition(), 0, true);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
TabLayout.Tab tabAt = mTabLayout.getTabAt(layoutManager.findFirstVisibleItemPosition());
if (tabAt != null && !tabAt.isSelected()) {
tabAt.select();
}
}
});
3、最后的空白处怎么做的?
就是多了个foot,动态计算高度。
class AppGroupAdapter extends RecyclerView.Adapter{
public static final int VIEW_TYPE_ITEM = 1;
public static final int VIEW_TYPE_FOOTER = 2;
protected List<AppGroup> mData;
/**
* item高度
*/
private int itemHeight;
private Context context;
public AppGroupAdapter(List<AppGroup> data, Context context){
mData = data;
this.context = context;
// mRecycledViewPool = new RecyclerView.RecycledViewPool();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(context).inflate(R.layout.app_group, parent, false);
return new ItemVH(view);
} else {
//Footer是最后留白的位置,以便最后一个item能够出发tab的切换
View view = new View(context);
Log.e("footer", "parentHeight: " + mRecyclerViewHeight + "--" + "itemHeight: " + itemHeight);
view.setLayoutParams(
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
mRecyclerViewHeight - itemHeight));
return new FootVH(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == VIEW_TYPE_ITEM){
final ItemVH vh = (ItemVH) holder;
vh.tvGroup.setText(mData.get(position).getName());
vh.recyclerView.setRecycledViewPool(mRecycledViewPool);
vh.recyclerView.setHasFixedSize(false);
// vh.recyclerView.setNestedScrollingEnabled(false);
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 4){
@Override
public boolean canScrollVertically() {
return false;
}
@Override
public void onLayoutCompleted(RecyclerView.State state) {
super.onLayoutCompleted(state);
mRecyclerViewHeight = mRecyclerView.getHeight();
itemHeight = vh.itemView.getHeight();
}
};
gridLayoutManager.setOrientation(RecyclerView.VERTICAL);
vh.recyclerView.setLayoutManager(gridLayoutManager);
AppsAdapter appsAdapter = new AppsAdapter(context);
appsAdapter.list.addAll(mData.get(position).getApps());
vh.recyclerView.setAdapter(appsAdapter);
}
}
@Override
public int getItemCount() {
return mData.size() + 1;
}
@Override
public int getItemViewType(int position) {
if (position == mData.size()) return VIEW_TYPE_FOOTER;
return VIEW_TYPE_ITEM;
}
class FootVH extends RecyclerView.ViewHolder{
public FootVH(@NonNull View itemView) {
super(itemView);
}
}
class ItemVH extends RecyclerView.ViewHolder{
private TextView tvGroup;
private RecyclerView recyclerView;
public ItemVH(@NonNull View itemView) {
super(itemView);
tvGroup = itemView.findViewById(R.id.tv_name);
recyclerView = itemView.findViewById(R.id.recycler);
}
}
}