AndroidrecyclerView.addView用法
时间: 2023-09-01 13:11:04 浏览: 63
在 Android 中,RecyclerView 是一个强大的控件,可以用于展示大量数据,并支持各种布局方式。通常,我们会通过 RecyclerView.Adapter 来为 RecyclerView 提供数据。在 Adapter 中,我们需要实现一个 ViewHolder 类来表示 RecyclerView 中的每一个元素,ViewHolder 中包含了一个 View 对象,用于显示元素的布局。
如果我们想在 RecyclerView 中添加一个新的 View,可以使用 RecyclerView.addView() 方法。这个方法的参数是一个 View 对象,表示要添加到 RecyclerView 中的元素。注意,这个方法只能在主线程中调用,否则会抛出异常。
示例代码如下:
```java
View view = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);
recyclerView.addView(view);
```
这段代码会将一个名为 item_layout 的布局文件转换成一个 View 对象,并将其添加到 RecyclerView 中。其中,parent 参数表示 RecyclerView 的父容器,false 参数表示不需要将 view 直接附加到 parent 上,而是在将 view 添加到 RecyclerView 时再附加到 parent 上。
相关问题
RecyclerView android 纵向自动滚动实现
RecyclerView 的纵向自动滚动实现可以使用 RecyclerView 自带的 LayoutManager 或者自定义 LayoutManager 实现。
使用 RecyclerView 自带的 LayoutManager 实现纵向自动滚动:
1. 获取 RecyclerView 的 LinearLayoutManager 对象
2. 创建一个 Handler 对象和一个 Runnable 对象
3. 在 Runnable 的 run() 方法中,调用 LinearLayoutManager 的 smoothScrollToPosition() 方法实现自动滚动
4. 在 Handler 中使用 postDelayed() 方法,指定延迟时间和 Runnable 对象,实现定时滚动。
示例代码如下:
```
private LinearLayoutManager mLinearLayoutManager;
private Handler mHandler = new Handler();
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
int currentPos = mLinearLayoutManager.findFirstVisibleItemPosition();
mLinearLayoutManager.smoothScrollToPosition(mRecyclerView, null, currentPos + 1);
mHandler.postDelayed(this, 3000); // 延迟 3 秒滚动
}
};
private void initRecyclerView() {
mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
private void startAutoScroll() {
mHandler.postDelayed(mRunnable, 3000); // 延迟 3 秒滚动
}
private void stopAutoScroll() {
mHandler.removeCallbacks(mRunnable);
}
```
使用自定义 LayoutManager 实现纵向自动滚动:
1. 自定义一个继承自 LinearLayoutManager 的 LayoutManager
2. 在 LayoutManager 的 onLayoutChildren() 方法中,调用 super.onLayoutChildren() 方法完成布局,并获取第一个和最后一个可见 item 的位置
3. 在 LayoutManager 的 scrollVerticallyBy() 方法中,判断当前滑动的距离是否大于等于一个屏幕的高度,如果是,则调用 scrollToPosition() 方法实现自动滚动。
示例代码如下:
```
public class AutoScrollLayoutManager extends LinearLayoutManager {
private int mScreenHeight;
public AutoScrollLayoutManager(Context context) {
super(context);
mScreenHeight = context.getResources().getDisplayMetrics().heightPixels;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
int firstVisiblePos = findFirstVisibleItemPosition();
int lastVisiblePos = findLastVisibleItemPosition();
if (lastVisiblePos - firstVisiblePos < state.getItemCount() - 1) { // 如果可见 item 数量小于总 item 数量,强制重新布局
detachAndScrapAttachedViews(recycler);
layoutChildren(recycler, state);
}
}
private void layoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
int offsetY = 0;
for (int i = 0; i < getItemCount(); i++) {
View view = recycler.getViewForPosition(i);
addView(view);
measureChildWithMargins(view, 0, 0);
int width = getDecoratedMeasuredWidth(view);
int height = getDecoratedMeasuredHeight(view);
layoutDecorated(view, 0, offsetY, width, offsetY + height);
offsetY += height;
}
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
int travel = dy;
if (dy > 0) { // 手指向上滑动
View lastVisibleView = getChildAt(getChildCount() - 1);
int lastVisiblePos = getPosition(lastVisibleView);
if (lastVisibleView.getBottom() - dy < mScreenHeight) { // 如果最后一个可见 item 没有完全显示,就不滑动
travel = 0;
} else if (lastVisiblePos == getItemCount() - 1) { // 如果滑到最后一个 item,就不滑动
travel = 0;
}
}
int realScroll = super.scrollVerticallyBy(travel, recycler, state);
if (realScroll != travel) { // 如果滑动距离小于手指滑动距离,说明已经滑到边界了,就自动滚动
int currentPos = findFirstVisibleItemPosition();
scrollToPosition(currentPos + 1);
}
return realScroll;
}
}
```
使用自定义的 AutoScrollLayoutManager:
```
private AutoScrollLayoutManager mLayoutManager;
private void initRecyclerView() {
mLayoutManager = new AutoScrollLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
private void startAutoScroll() {
mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount() - 1); // 先滚动到最后一个 item
mHandler.postDelayed(mRunnable, 3000); // 延迟 3 秒开始自动滚动
}
private void stopAutoScroll() {
mHandler.removeCallbacks(mRunnable);
}
```
recyclerview 仿快手头像挂饰的条目选择全代码
好的,以下是一个基于RecyclerView和自定义LayoutManager实现快手头像挂饰的条目选择效果的完整代码:
AvatarDecorationLayoutManager.java:
```
public class AvatarDecorationLayoutManager extends RecyclerView.LayoutManager {
private int mVerticalScrollOffset = 0; // 竖直方向的偏移量
private int mTotalHeight = 0; // 总高度
private int mItemWidth = 0; // 每个条目的宽度
private int mItemHeight = 0; // 每个条目的高度
private int mSpace = 10; // 每个挂饰之间的间距
private int mMaxItemCountInLine = 5; // 每行最大的挂饰数量
private SparseArray<Rect> mItemFrames = new SparseArray<>(); // 保存每个条目的位置信息
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() == 0 || state.isPreLayout()) {
return;
}
detachAndScrapAttachedViews(recycler); // 移除所有已经添加的View
mItemWidth = (getWidth() - getPaddingLeft() - getPaddingRight() - (mMaxItemCountInLine - 1) * mSpace) / mMaxItemCountInLine;
mItemHeight = mItemWidth; // 每个条目的高度和宽度相等
int left = getPaddingLeft();
int top = getPaddingTop();
int lineMaxHeight = 0; // 当前行中最高的挂饰的高度
for (int i = 0; i < getItemCount(); i++) {
View view = recycler.getViewForPosition(i);
addView(view);
measureChildWithMargins(view, 0, 0);
int width = getDecoratedMeasuredWidth(view);
int height = getDecoratedMeasuredHeight(view);
if (i % mMaxItemCountInLine == 0) { // 每行第一个挂饰
left = getPaddingLeft();
top += lineMaxHeight + mSpace; // 上一行中最高挂饰的高度加上间距作为当前行的起始位置
lineMaxHeight = 0;
}
Rect rect = new Rect(left, top, left + mItemWidth, top + mItemHeight);
mItemFrames.put(i, rect);
left += mItemWidth + mSpace;
lineMaxHeight = Math.max(lineMaxHeight, height); // 更新当前行中最高挂饰的高度
}
mTotalHeight = top + lineMaxHeight + getPaddingBottom(); // 计算总高度
mTotalHeight = Math.max(mTotalHeight, getVerticalSpace()); // 总高度不能小于RecyclerView的高度
recycleAndFillItems(recycler, state);
}
@Override
public boolean canScrollVertically() {
return true;
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
int travel = dy;
if (mVerticalScrollOffset + dy < 0) {
travel = -mVerticalScrollOffset;
} else if (mVerticalScrollOffset + dy > mTotalHeight - getVerticalSpace()) {
travel = mTotalHeight - getVerticalSpace() - mVerticalScrollOffset;
}
mVerticalScrollOffset += travel;
offsetChildrenVertical(-travel);
recycleAndFillItems(recycler, state);
return travel;
}
private void recycleAndFillItems(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() == 0 || state.isPreLayout()) {
return;
}
Rect visibleRect = new Rect(
getPaddingLeft(),
getPaddingTop() + mVerticalScrollOffset,
getWidth() - getPaddingRight(),
getVerticalSpace() + mVerticalScrollOffset - getPaddingBottom());
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
int position = getPosition(view);
if (!Rect.intersects(visibleRect, mItemFrames.get(position))) {
removeAndRecycleView(view, recycler);
}
}
for (int i = 0; i < getItemCount(); i++) {
if (Rect.intersects(visibleRect, mItemFrames.get(i))) {
View view = recycler.getViewForPosition(i);
measureChildWithMargins(view, 0, 0);
addView(view);
Rect rect = mItemFrames.get(i);
layoutDecoratedWithMargins(view, rect.left, rect.top - mVerticalScrollOffset, rect.right, rect.bottom - mVerticalScrollOffset);
}
}
}
private int getVerticalSpace() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
}
```
AvatarDecorationAdapter.java:
```
public class AvatarDecorationAdapter extends RecyclerView.Adapter<AvatarDecorationAdapter.ViewHolder> {
private List<AvatarDecoration> mAvatarDecorations;
public AvatarDecorationAdapter(List<AvatarDecoration> avatarDecorations) {
mAvatarDecorations = avatarDecorations;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_avatar_decoration, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
AvatarDecoration avatarDecoration = mAvatarDecorations.get(position);
holder.mAvatarImageView.setImageResource(avatarDecoration.getAvatarResId());
holder.mDecorationImageView.setImageResource(avatarDecoration.getDecorationResId());
holder.itemView.setSelected(avatarDecoration.isSelected());
}
@Override
public int getItemCount() {
return mAvatarDecorations.size();
}
public void toggleSelection(int position) {
AvatarDecoration avatarDecoration = mAvatarDecorations.get(position);
avatarDecoration.setSelected(!avatarDecoration.isSelected());
notifyItemChanged(position);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView mAvatarImageView;
ImageView mDecorationImageView;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImageView = itemView.findViewById(R.id.avatar_image_view);
mDecorationImageView = itemView.findViewById(R.id.decoration_image_view);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((RecyclerView) v.getParent()).getAdapter().notifyItemChanged(getAdapterPosition());
}
});
}
}
}
```
AvatarDecoration.java:
```
public class AvatarDecoration {
private int mAvatarResId;
private int mDecorationResId;
private boolean mSelected;
public AvatarDecoration(int avatarResId, int decorationResId) {
mAvatarResId = avatarResId;
mDecorationResId = decorationResId;
mSelected = false;
}
public int getAvatarResId() {
return mAvatarResId;
}
public void setAvatarResId(int avatarResId) {
mAvatarResId = avatarResId;
}
public int getDecorationResId() {
return mDecorationResId;
}
public void setDecorationResId(int decorationResId) {
mDecorationResId = decorationResId;
}
public boolean isSelected() {
return mSelected;
}
public void setSelected(boolean selected) {
mSelected = selected;
}
}
```
item_avatar_decoration.xml:
```
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="4dp">
<ImageView
android:id="@+id/avatar_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<ImageView
android:id="@+id/decoration_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:src="@drawable/ic_decoration"
android:visibility="gone" />
</FrameLayout>
```
使用时,可以在Activity或Fragment中初始化RecyclerView:
```
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new AvatarDecorationLayoutManager());
recyclerView.setAdapter(new AvatarDecorationAdapter(avatarDecorations));
```
其中,avatarDecorations是一个List,保存了所有的头像和挂饰的信息。
在点击事件中,可以通过调用Adapter的toggleSelection方法来切换条目的选中状态。
完整的示例代码可以在我的GitHub仓库中找到:https://github.com/linroid/AvatarDecorationRecyclerView
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)