自定义List View下拉顶部视图放大缩小

首先先说思路

1创建MyListView类 extends ListView 重写三个构造方法,

2在xml里面引用<com.example.yangai00.yy_shuxingdonghua.MyListView  然后在MainActivity里面初始化控件

3获取数据,调用适配器(我用的是系统默认的)适配数据  重写getView()方法(适配器里面细节。。。。。略)

4引入顶部试图,调用addHeaderView(”添加引入的布局的View“),初始化控件

5在MyListView里面自定义方法getImgView(要引入的顶部试图控件);

6在MainActivity里面调用getImgView(传入第4步引入顶部试图的初始化控件ID)

7在getImgView()里面通过传入的参数给全局变量赋值(this.IV = v),然后IV.调用

getViewTreeObserver().addOnGlobalLayoutListener()方法,重写onGlobalLayout()方法,在onGlobalLayout()方法里面获取控件的高度(IV.getHeight()),防止此方法可能会多次调用,定义boolean类型变量为true,if判断之后重新给boolean变量重新赋值为false

8在通过调用getDrawable().getIntrinsicHeight()方法来获取图片的高度;

9比较控件的高度和图片的高度,最后把大的值,赋值给新的int 类型的max变量

10重写overScrollBy();参数.deltaX 是x轴向上滑动的距离,参数.deltaY是Y轴向上滑动的距离,参数:maxOverScrollX  是X轴滑动的最大距离 maxOverScrollY 是Y轴滑动的最大距离,参数:isTouchEvent  为true代表滑动  为false代表惯性滑动,在overScrollBy()方法里面首先ImageView判空  接着在判断是否是向下滑动和isTouchEvent是为true,如果条件成立,证明是在向下滑动,我们要获取当前滑动的高度,在判断如果当前的高度大于第9步中的max(最大高度)就把max最大的高度赋值给当前的高度,在把当前获得的新的高度赋值给图片的高度,然后调用requestLayout()方法刷新

11 重写onTouchEvent手势监听方法,在手势抬起的时候添加属性动画,通过属性动画让图片回弹 ,首先导入implementation files('libs/nineoldandroids-2.2.0.jar')依赖,通过ObjectAnimator.ofInt(参数:当前的高度,原始的高度)方法创建动画,获取动画的监听器,在监听器里面通过valueAnimator.getAnimatedValue()方法来获取动画的已个过度值(0.....1),通过setIntValues()来设置过度值,接着设置动画的时间,开启动画。

这只是已个简单的自定义listView顶部图片下拉放大和回弹效果,写了这么多,只是为了大家好更好的理解。

思路说完了下面是代码展示:

自定义ListView类:

public class MyListView extends ListView {
//顶部图片
    private ImageView IV;
//当前的高度
    private int div;

    public MyListView(Context context) {
        super(context);
    }

    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
//控件的高
    private int kong_height;
//图片的高
    private int tu_height;
//最大高度
    private int mMaxheight;

    private Boolean feng = true;
//自定义方法用于传ImageView 
    public void getImgView(ImageView v) {
        this.IV = v;
        IV.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
//在此处获取控件的高度,为了只获取一次,加个Boolean判断
                if (feng) {
                    kong_height = IV.getHeight();
                    feng = false;
                }
            }
        });
//获取图片的高度
        tu_height = IV.getDrawable().getIntrinsicHeight();
//把大的值赋值给最大高度
        mMaxheight = kong_height > tu_height ? kong_height + 200 : tu_height;

    }
//用于记录滑动的时候的x和y轴坐标
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        if (IV != null) {
//判断是否向下和滑动
            if (deltaY < 0 && isTouchEvent) {
//获取当前高度
                div = IV.getHeight() - deltaY;
//当前高度大于最大高度把最大高度赋值给当前高度
                if (div > mMaxheight) {
                    div = mMaxheight;
                }
//把获取到 的新高度赋值给params.height进行拉伸
                ViewGroup.LayoutParams params = IV.getLayoutParams();
                params.height = div;
//刷新
                requestLayout();
            }
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
                scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }
//手势监听
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
//手指抬起
            case MotionEvent.ACTION_UP:
//添加属性动画进行回弹IV.getHeight为下拉后当前高度,kong_height为原始状态
                ValueAnimator valueAnimator = com.nineoldandroids.animation.ObjectAnimator.ofInt(IV.getHeight(), kong_height);
                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        int animatedValue = (int) valueAnimator.getAnimatedValue();
                        IV.getLayoutParams().height = animatedValue;
                        requestLayout();

                    }
                });
//动画时间
                valueAnimator.setDuration(100);
//开始
                valueAnimator.start();
                break;
        }
        return super.onTouchEvent(ev);
    }
}

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"
    android:orientation="vertical">

    <com.example.yangai00.yy_shuxingdonghua.MyListView
        android:id="@+id/mLV"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="#000"
        android:dividerHeight="1dp">

    </com.example.yangai00.yy_shuxingdonghua.MyListView>

</LinearLayout>

主页面:

public class MainActivity extends AppCompatActivity {
//初始化控件
    private MyListView mLV;
//linstView数据
    private String[] yun = {"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "I", "O", "P", "U", "Y", "T", "R", "W", "Q", "S", "L", "Z", "X", "V", "N", "M"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
    }
    private void initData() {
//创建适配器
        ArrayAdapter<String> MyAdaptes = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_expandable_list_item_1, yun) {
            @NonNull
            @Override
            public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                if (convertView == null) {
                    convertView = View.inflate(MainActivity.this, R.layout.my_listview, null);
                    TextView mTV = convertView.findViewById(R.id.mText);
                    mTV.setText(yun[position]);
                }
                return convertView;
            }
        };
        mLV.setAdapter(MyAdaptes);
//添加listView顶部View试图
        View v = View.inflate(MainActivity.this, R.layout.my_img, null);
        mLV.addHeaderView(v);
        ImageView viewById = v.findViewById(R.id.mImg);
//将ImageView的ID传到适配器
        mLV.getImgView(viewById);

    }

    private void initView() {
//初始化
        mLV = (MyListView) findViewById(R.id.mLV);

    }
}

 

其他的两个xml布局就不展示了 ,到此整个代码结束。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值