RecyclerView设置header(或者footer)/端部避免半月形阴影

这篇博客介绍了如何在Android中去除RecyclerView在下拉时出现的半月形阴影,通过设置`android:overScrollMode="never"`和`android:fadingEdge="none"`可以消除阴影和虚化效果。同时,文章详细讲解了如何为RecyclerView添加header,包括编写header布局、自定义adapter和在MainActivity中实例化并传入header视图的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

端部避免半月形阴影

在android5.0当中正常的listview/scrollview在下拉的时候顶部会出现半月形的阴影效果,

先要去除这个小效果可以设置

android:overScrollMode=“never”

就可以去掉这些效果。这句是用来去掉系统自带的阴影

正常的listview/scrollview在进入和滑出控件边界的时候会出现一层虚化的效果:

为了去除虚化的效果可以使用

android:fadingEdge=“none”

这样就去掉了虚化的效果


header(或者footer)效果图

设置header需要以下3个步骤:

1、编写header.xml的布局

2、编写adapter

3、在MainActivity中实例化布局成View并把view传入到adapter


1、编写header.xml的布局

header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="150dp">
    <TextView
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="我是Header"
        android:textSize="30sp"
        android:textColor="#fde70b0b"
        android:background="#f9777979"
        android:gravity="center"/>
</LinearLayout>


2、编写adapter

FruitAdapter
public class FruitAdaptor extends RecyclerView.Adapter<FruitAdaptor.ViewHolder> {
    private List<Fruit> fruits;
    public static View header;
    public static final int HEADER_NORMAL=0;
    public static final int HEADER=1;
    public static final int NORMAL=2;

    public FruitAdaptor(List<Fruit> fruits) {
        this.fruits = fruits;
    }
    /**
     * 用于把header.xml初始化成view并传进来
     * @param view
     */
    public void setHeader(View view){
        this.header=view;
        notifyItemInserted(0);  //以观察者的模式,如果调用此方法则把position=0的item占用
    }
    /**
     * 如果设置footer,则用此方法
     * @param view
     */
    public void setFooter(View view){
        this.footer=view;
        //以观察者的模式,如果调用此方法则把position=getItemCount()-1的item占用
        notifyItemInserted(getItemCount()-1);
    }
    /**
     * 得到每个item的类型
     * 1、如果没有header,则返回NORMAL
     * 2、如果有header,且position=0,则返回HEADER
     *                  且position!=0,则返回HEADER_NORMAL
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        if (header==null){
            return NORMAL;
        }else {
            if (position==0){
                return HEADER;
            }else {
                return HEADER_NORMAL;
            }
        }
    }
    /**
     * 创建item中的viewholder
     * 1、没有header或者有header但是不占用header位置的item正常返回viewholder
     * 2、有header并且position=0的item返回装有header.xml的viewholder
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        if (viewType==NORMAL||viewType==HEADER_NORMAL){
            final View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit,parent,false);
            final ViewHolder viewHolder=new ViewHolder(view);
            return viewHolder;
        }else {
            return new ViewHolder(header);
        }
    }
    /**
     * 绑定每个item的数据
     * 1、如果没有header(就是没有执行setHeader方法),则不执行notifyItemInserted(0)
     * 2、与此相反,执行了notifyItemInserted(0)之后。position=0的item则装上了header.xml,
     *    所以装数据的item的position从1开始(0被header占了)
     * 3、如果有header并且position=0时,则立即返回,结束方法,因为header没有数据可以存取
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if (getItemViewType(position)==NORMAL){
            Fruit fruit=fruits.get(position);
            holder.imageView.setImageResource(fruit.getImageId());
            holder.textView.setText(fruit.getName());
        }else if (getItemViewType(position)==HEADER){
            return;
        }else {
            Fruit fruit=fruits.get(position-1); //有header的情况下position从1开始,所以position-1
            holder.imageView.setImageResource(fruit.getImageId());
            holder.textView.setText(fruit.getName());
        }
    }
    /**
     * 设置总的item数目
     * 1、没有header为fruits.size()
     * 2、有header再加一个header数目,即fruits.size()+1
     * @return
     */
    @Override
    public int getItemCount() {
        if (header!=null){
            return fruits.size()+1;
        }
        return fruits.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder{
        View view;
        ImageView imageView;
        TextView textView;
        /**
         *viewholder的构造函数
         * 1、如果传进来的view是header,则立即返回,结束此方法(因为header的布局与item其他的布局不同)
         * 2、如果传进来的view不是header,则正常存取值
         */
        public ViewHolder(View view1){
            super(view1);
            if (view1==FruitAdaptor.header){
                return;
            }else {
                view=view1;
                imageView=(ImageView)view.findViewById(R.id.image_view);
                textView=(TextView)view.findViewById(R.id.text_view);
            }
        }
    }
}

先设置setHeader方法传进来header的view,再重写getItemCount获取item的总数,重写getItemViewType得到有没有header和不同position的item类型,在重写onCreatViewHolder按类型把数据存进viewHolder(如果是header类型则利用viewHolder的构造方法不存进去数据),最后利用onBindViewHolder根据不同类型从viewHolder中获取数据(注意有header的情况则position-1)


3、在MainActivity中实例化布局成View并把view传入到adapter

MainActivity
public class MainActivity extends AppCompatActivity {
    private List<Fruit> fruits=new ArrayList<Fruit>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruit();	//模拟每个item中的数据
        RecyclerView recyclerView=(RecyclerView)findViewById(R.id.recycler_view);
        FruitAdapter fruitAdapter=new FruitAdapter(fruits);
        final LinearLayoutManager linearLayoutManager=new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(fruitAdapter);
        //实例化header.xml并传入fruitAdapter
        fruitAdapter.setHeader(LayoutInflater.from(this).inflate(R.layout.header,null));
    }




footer与此同理。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值