这是我参与「第四届青训营 」笔记创作活动的的第32天
作者: Eric0202
前言:
大作业是写一个简单版的抖音,根据团队安排, 我个人主要是写 《我的》页面, 那么久来分析一下抖音 《我的》页面的布局画法吧。
正文:
1. 总体布局
这是一个需要滑动的界面,明显下滑后应该从作品上方分开,作品等四个tab保留在顶部, 其他部分隐藏,因此分为两个部分。首先分析下下面的作品部分, 比较简单。
2. 作品布局
tab
这里是一个tabLayout
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="50dp" />
定义一个宽度matchparent的tab,只需要写死高度,定好id,内容可以之后在java代码中通过id加上
viewpager
这一部分就是viewpager 里面加载recyclerview和adapter,item实现
这里用的是recyclerview,一般也可以用gridview来写,简单的在xml里面写一个gridview, 然后将宽度占满,注意一定不要忘记id, 通过id和adapter向里面填充数据
里面的每一个item的布局,首先是背景的图片,然后是一个播放按钮和一个观看数字,也可以在左上角放一个 《置顶》的标签。
最简单的做法我觉得应该用constraitlayout, constraintlayout是谷歌比较推荐的做法,优点是在画复杂布局时避免的layout嵌套。
做法:
-
itemlayout的imageview填满整个布局,constraint个四个方向都和parent对齐
-
一个小的imageview,start to parent start, bottom to parent buttom, 然后写上id
这里用start而不是left,left依然可以生效,但是现在一般都建议用start了
-
一个小的textview,字体白色,start to 之前的小image 的 end, bottom to parent bottom
完成。
对于image的加载, 我觉得glide是要明显优于系统自带src的, 当图片稍多的时候,系统src的方法就会明显加载卡顿,glide依然非常迅速
layout:
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
recyclerview:
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView(@NonNull Context context) {
super(context);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 记录上一次滑动的坐标
private int mLastX,mLastY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int)ev.getX();
int y = (int)ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
getParent().requestDisallowInterceptTouchEvent(true);
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
}
case MotionEvent.ACTION_UP:{
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(ev);
}
}
fragment内的layout:
<com.byteteam.douyin.widget.MyRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
item:
item的代码就有点多,避免代码远超文字, 就不放出来了。