自定义 ListView 实现图片的拉伸放大;松手图片还原

采用创建一个类: HeaderListView ,继承 ListView 来实现;

效果图如下:


activity_main.xml 的布局文件如下:


<span style="font-size:18px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <!--android:cacheColorHint="@android:color/transparent" 滚动ListView时不会掉黑 。
    滚动时,重绘View的时候就不会有背景颜色。-->
    <com.crazy.headerlistviewtest.HeaderListView
        android:id="@+id/lv_header"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent">

    </com.crazy.headerlistviewtest.HeaderListView>

</RelativeLayout>
</span>



item_layout.xml 布局如下:


<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="65dp"
        android:layout_height="65dp"
        android:scaleType="fitXY"
        android:src="@drawable/image_1"/>

    <!--TextView 中的内容只是为了演示效果,真正显示的内容在枚举中-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="10dp">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="梦想"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="爱好学习,努力奋斗,玩玩游戏,喜欢优雅的环境,上进心强"
            android:textSize="14sp"/>

    </LinearLayout>

</LinearLayout></span>
示意图如下:




layout_header_view.xml 布局文件:


<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="150dp">

    <!-- android:scaleType="centerCrop"设置该属性 imageview 才可以缩放-->
    <ImageView
        android:id="@+id/iv_header"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:scaleType="centerCrop"
        android:src="@drawable/header1"/>

</RelativeLayout>
</span>
示意图如下:





<span style="font-size:18px;">package com.crazy.headerlistviewtest;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {

    // 定义显示的数据
    public enum Data{
        item_1("Crazy", "学习Android的学员", R.drawable.image_1),
        item_2("Crazy", "学习Android的学员", R.drawable.image_1),
        item_3("Crazy", "学习Android的学员", R.drawable.image_1),
        item_4("Crazy", "学习Android的学员", R.drawable.image_1),
        item_5("Crazy", "学习Android的学员", R.drawable.image_1),
        item_6("Crazy", "学习Android的学员", R.drawable.image_1),
        item_7("Crazy", "学习Android的学员", R.drawable.image_1),
        item_8("Crazy", "学习Android的学员", R.drawable.image_1),
        item_9("Crazy", "学习Android的学员", R.drawable.image_1),
        item_10("Crazy", "学习Android的学员", R.drawable.image_1),
        item_11("Crazy", "学习Android的学员", R.drawable.image_1),
        item_12("Crazy", "学习Android的学员", R.drawable.image_1);


        private String name;
        private String content;
        private int resId;

        private Data(String name, String content, int resId) {
            this.name = name;
            this.content = content;
            this.resId = resId;
        }

        public String getName() {
            return name;
        }

        public int getResId() {
            return resId;
        }

        public String getContent() {
            return content;
        }
    }

    private HeaderListView lv_header;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        initView();

    }

    private void initView() {
        lv_header = (HeaderListView)findViewById(R.id.lv_header);
        initHeaderView();// 要在 adapter 前设置
        MyAdapter myAdapter = new MyAdapter(this);
        lv_header.setAdapter(myAdapter);
    }

    private void initHeaderView(){
        View headerView = getLayoutInflater().inflate(R.layout.layout_header_view, null);
        ImageView iv_header = (ImageView)headerView.findViewById(R.id.iv_header); // 传入
        lv_header.setHeaderIV(iv_header);
        lv_header.addHeaderView(headerView);
    }

    public class MyAdapter extends BaseAdapter{

        public MyAdapter(Context context){

        }

        @Override
        public int getCount() {
            return Data.values().length;
        }

        @Override
        public Object getItem(int position) {
            return Data.values()[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder viewHolder = null;
            if (convertView == null){
                convertView = getLayoutInflater().inflate(R.layout.item_layout, parent, false);
                viewHolder = new ViewHolder();
                // 初始化
                viewHolder.iv = (ImageView)convertView.findViewById(R.id.iv);
                viewHolder.tv_name = (TextView)convertView.findViewById(R.id.tv_name);
                viewHolder.tv_content = (TextView)convertView.findViewById(R.id.tv_content);

                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder)convertView.getTag();
            }
            // 设置数据
            Data data = Data.values()[position];
            viewHolder.iv.setImageResource(data.resId);
            viewHolder.tv_name.setText(data.getName());
            viewHolder.tv_content.setText(data.getContent());
            return convertView;
        }

        class ViewHolder{
            ImageView iv;
            TextView tv_name;
            TextView tv_content;
        }
    }
}
</span>



<span style="font-size:18px;">package com.crazy.headerlistviewtest;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.ListView;


public class HeaderListView extends ListView {

    // 放大的 ImageView
    private ImageView headerIV;
    private int height;

    public void setHeaderIV(ImageView headerIV) {
        this.headerIV = headerIV;
    }

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

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

    public HeaderListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 当 view 依附到 activity 上面的时候回调
     * @param hasWindowFocus
     */
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);

        if (hasWindowFocus){
            height = this.headerIV.getHeight();
        }
    }

    /**
     *  当listview 滚动到顶部的时候,还要下拉,还要网上滚动,那么这时就会调用该方法
     * @param deltaX
     * @param deltaY
     * @param scrollX
     * @param scrollY
     * @param scrollRangeX
     * @param scrollRangeY
     * @param maxOverScrollX
     * @param maxOverScrollY
     * @param isTouchEvent
     * @return
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

        // 滑动过头的时候回调该方法
        // 控制 imageview 的高度逐渐增加------从而达到滚动图片放大的效果
        boolean isCollpse = resizeOverScrollBy(deltaY);

        return isCollpse == false ? isCollpse: super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    private boolean resizeOverScrollBy(int deltaY) {

        if (deltaY < 0){
            if (headerIV != null){
                // 当滑动到顶部的时候,还要网上滑动,就改变 imageview 的高度
                headerIV.getLayoutParams().height = headerIV.getHeight() - deltaY;
                headerIV.requestLayout();
            }
        } else {
            if (headerIV != null){
                headerIV.getLayoutParams().height = headerIV.getHeight() - deltaY;
                headerIV.requestLayout();
            }
        }
        return false;
    }

    /**
     * 当listview 没有滑动到底部或顶部时调用
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        // 还原图片,保持imageview 的初始化高度
        // 获取imageview 的父容器(RelativeLayout)
        ViewParent parent = this.headerIV.getParent();
        if (parent != null){
            View rootView = (View)parent;
            if (rootView.getTop() < 0 && headerIV .getHeight() > height){

                headerIV.getLayoutParams().height = headerIV.getHeight() + rootView.getTop();

                // 重新摆放子控件
                rootView.layout(rootView.getLeft(), 0, rootView.getRight(), rootView.getBottom());

                // 重新绘制
                headerIV.requestLayout();
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // 监听手势抬起
        if (ev.getAction() == MotionEvent.ACTION_UP){
            MyAnimation animation = new MyAnimation(headerIV, height);
            animation.setDuration(300);
            this.headerIV.startAnimation(animation);
        }
        return super.onTouchEvent(ev);
    }

    public class MyAnimation extends Animation{

        private ImageView imageView;
        // imageview 的原始高度
        private int targetHeight;
        // 当前 imageview 的高度
        private int currentHeight;
        // 高度差 当前的减去原始的
        private int extraHeight;

        public MyAnimation(ImageView imageView, int targetHeight){
            this.imageView = imageView;
            this.targetHeight = targetHeight;
            this.currentHeight = imageView.getHeight();
            this.extraHeight = this.currentHeight - this.targetHeight;
        }

        /**
         *  当动画在不断的执行的时候回调该方法(就是监听动画执行的过程)
         * @param interpolatedTime 值得范围 0.0 到 1.0,时间变化因子
         * @param t
         */
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);

            this.imageView.getLayoutParams().height = (int)(this.currentHeight
                    - extraHeight * interpolatedTime);

            this.imageView.requestLayout();
        }
    }
}
</span>



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
首先,你需要准备一个包含图片资源的数组或列表。然后,你可以使用 Listview自定义适配器来显示图片。 下面是一个简单的示例代码: 1. 在布局文件中添加 Listview 组件: ``` <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在 Activity 或 Fragment 中获取 Listview 组件,并将适配器设置为自定义适配器: ``` ListView listView = findViewById(R.id.listview); MyAdapter adapter = new MyAdapter(this, R.layout.list_item, myList); listView.setAdapter(adapter); ``` 3. 创建自定义适配器类 MyAdapter,继承自 BaseAdapter,并实现 getView() 方法: ``` public class MyAdapter extends BaseAdapter { private Context context; private int layoutResourceId; private List<MyItem> data; public MyAdapter(Context context, int layoutResourceId, List<MyItem> data) { this.context = context; this.layoutResourceId = layoutResourceId; this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; ViewHolder holder = null; if (row == null) { LayoutInflater inflater = ((Activity) context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); holder = new ViewHolder(); holder.imageView = row.findViewById(R.id.image_view); holder.textView = row.findViewById(R.id.text_view); row.setTag(holder); } else { holder = (ViewHolder) row.getTag(); } MyItem item = data.get(position); holder.textView.setText(item.getText()); holder.imageView.setImageResource(item.getImageResourceId()); return row; } static class ViewHolder { ImageView imageView; TextView textView; } } ``` 4. 创建类 MyItem,用于存储列表项的数据,包括图片资源 ID 和文本内容: ``` public class MyItem { private int imageResourceId; private String text; public MyItem(int imageResourceId, String text) { this.imageResourceId = imageResourceId; this.text = text; } public int getImageResourceId() { return imageResourceId; } public String getText() { return text; } } ``` 5. 最后,创建一个包含图片资源的数组或列表,并将其传递给适配器: ``` List<MyItem> myList = new ArrayList<>(); myList.add(new MyItem(R.drawable.image1, "Item 1")); myList.add(new MyItem(R.drawable.image2, "Item 2")); myList.add(new MyItem(R.drawable.image3, "Item 3")); ``` 以上就是使用 ListView 实现图片转换的基本步骤,你可以根据自己的需求进行适当的修改和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值