Android常用开源项目(二十三)

来源:互联网 发布:为什么学java 编辑:程序博客网 时间:2024/05/21 06:27


Android开发之在ListView头部实现图片下拉放大效果

1.首先看下实现的效果图

Android开发之在ListView头部实现图片下拉放大效果

2.具体实现步骤

Android开发之在ListView头部实现图片下拉放大效果

代码结构图

(1).实现自定义的ListView

public class ImgListView extends ListView {

private static final int BACK_SCALE = 0;

private boolean isHaveHead = false;// 头部是否有图片

private float scaleY = 0;

private boolean isBacking = false;// 是否处在回弹状态

private int displayWidth;

private Context mContext;

private Bitmap bmp;

private View headerView;

private ImageView imageView;

/** 用于记录拖拉图片移动的坐标位置 */

private Matrix matrix = new Matrix();

/** 用于记录图片要进行拖拉时候的坐标位置 */

private Matrix currentMatrix = new Matrix();

private Matrix defaultMatrix = new Matrix();

private float imgHeight, imgWidth;

/** 记录是拖拉照片模式还是放大缩小照片模式 0:拖拉模式,1:放大 */

private int mode = 0;// 初始状态

/** 拖拉照片模式 */

private final int MODE_DRAG = 1;

/** 用于记录开始时候的坐标位置 */

private PointF startPoint = new PointF();

private int mImageId;

private AttributeSet attrs;

public ImgListView(Context context) {

super(context);

this.mContext = context;

initView();

}

public ImgListView(Context context, AttributeSet attrs) {

super(context, attrs);

this.mContext = context;

this.attrs = attrs;

initView();

}

public ImgListView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

this.mContext = context;

this.attrs = attrs;

initView();

}

public void setAdapter(ListAdapter adapter) {

super.setAdapter(adapter);

}

public void addHeaderView(View v) {

super.addHeaderView(v);

}

public void setImageId(int id) {

this.mImageId = id;

bmp = BitmapFactory.decodeResource(getResources(), mImageId);

if (isHaveHead)

this.removeHeaderView(headerView);

initHead();

}

public void setImageBitmap(Bitmap bit) {

this.bmp = bit;

if (isHaveHead)

this.removeHeaderView(headerView);

initHead();

}

/**

* 初始化图片

*/

private void initView() {

/* 取得屏幕分辨率大小 */

DisplayMetrics dm = new DisplayMetrics();

WindowManager mWm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

mWm.getDefaultDisplay().getMetrics(dm);

displayWidth = dm.widthPixels;

TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.ImgListView);

mImageId = a.getResourceId(R.styleable.ImgListView_headimage, 0);

a.recycle();

if (null == bmp && mImageId != 0) {

bmp = BitmapFactory.decodeResource(getResources(), mImageId);

initHead();

}

}

private void initHead() {

LayoutInflater inflater = LayoutInflater.from(mContext);

headerView = inflater.inflate(R.layout.top_img, null);

imageView = (ImageView) headerView.findViewById(R.id.imageView);

float scale = (float) displayWidth / (float) bmp.getWidth();// 1080/1800

matrix.postScale(scale, scale, 0, 0);

imageView.setImageMatrix(matrix);

defaultMatrix.set(matrix);

imgHeight = scale * bmp.getHeight();

imgWidth = scale * bmp.getWidth();

ListView.LayoutParams relativeLayout = new ListView.LayoutParams((int) imgWidth, (int) imgHeight);

imageView.setLayoutParams(relativeLayout);

this.addHeaderView(headerView);

isHaveHead = true;

}

/**

* 向下滑动让图片变大

*

* @param event

* @return

*/

public boolean onTouchEvent(MotionEvent event) {

if (!isHaveHead) {// 无头部图片

return super.onTouchEvent(event);

}

switch (event.getAction() & MotionEvent.ACTION_MASK) {

// 手指压下屏幕

case MotionEvent.ACTION_DOWN:

if (isBacking) {

return super.onTouchEvent(event);

}

int[] location = new int[2];

imageView.getLocationInWindow(location);

if (location[1] >= 0) {

mode = MODE_DRAG;

// 记录ImageView当前的移动位置

currentMatrix.set(imageView.getImageMatrix());

startPoint.set(event.getX(), event.getY());

}

break;

// 手指在屏幕上移动,改事件会被不断触发

case MotionEvent.ACTION_MOVE:

// 拖拉图片

if (mode == MODE_DRAG) {

float dx = event.getX() - startPoint.x; // 得到x轴的移动距离

float dy = event.getY() - startPoint.y; // 得到y轴的移动距离

// 在没有移动之前的位置上进行移动

if (dy / 2 + imgHeight <= 1.5 * imgHeight) {

matrix.set(currentMatrix);

float scale = (dy / 2 + imgHeight) / (imgHeight);// 得到缩放倍数

if (dy > 0) {

scaleY = dy;

ListView.LayoutParams relativeLayout = new ListView.LayoutParams((int) (scale * imgWidth), (int) (scale * imgHeight));

imageView.setLayoutParams(relativeLayout);

matrix.postScale(scale, scale, imgWidth / 2, 0);

imageView.setImageMatrix(matrix);

}

}

}

break;

// 手指离开屏幕

case MotionEvent.ACTION_UP:

// 当触点离开屏幕,图片还原

mHandler.sendEmptyMessage(BACK_SCALE);

case MotionEvent.ACTION_POINTER_UP:

mode = 0;

break;

}

return super.onTouchEvent(event);

}

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

switch (msg.what) {

case BACK_SCALE:

float scale = (scaleY / 2 + imgHeight) / (imgHeight);// 得到缩放倍数

if (scaleY > 0) {

isBacking = true;

matrix.set(currentMatrix);

ListView.LayoutParams relativeLayout = new ListView.LayoutParams((int) (scale * imgWidth), (int) (scale * imgHeight));

imageView.setLayoutParams(relativeLayout);

matrix.postScale(scale, scale, imgWidth / 2, 0);

imageView.setImageMatrix(matrix);

scaleY = (float) (scaleY / 2 - 1);

mHandler.sendEmptyMessageDelayed(BACK_SCALE, 20);

} else {

scaleY = 0;

ListView.LayoutParams relativeLayout = new ListView.LayoutParams((int) imgWidth, (int) imgHeight);

imageView.setLayoutParams(relativeLayout);

matrix.set(defaultMatrix);

imageView.setImageMatrix(matrix);

isBacking = false;

}

break;

default:

break;

}

super.handleMessage(msg);

}

};

}

(2).listview的头部布局文件top_img.xml

<?xml version="1.0" encoding="utf-8"?>

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/imageView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:scaleType="matrix"

android:src="@drawable/top_img"

android:background="#EEEEEE"

/>

(3).新建Activity类,实现之定义listview的显示

public class MainActivity extends Activity {

private Context sContext;

private List<String> sNewsList;

private NewsAdapter sNewsAdapter;

private ImgListView sListView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

sContext = this;

sNewsList = new ArrayList<String>();

geneItems();

sListView = (ImgListView) findViewById(R.id.xListView);

//sListView.setImageId(R.drawable.top_img);//可以再资源文件中通过 imglistview:headimage="@drawable/top_img" 设置图片,也可通过本方法

sNewsAdapter = new NewsAdapter();

sListView.setAdapter(sNewsAdapter);

}

private void geneItems() {

for (int i = 0; i != 10; ++i) {

sNewsList.add(""+i);

}

}

private class NewsAdapter extends BaseAdapter {

private LayoutInflater mInflater;

public NewsAdapter() {

mInflater = LayoutInflater.from(sContext);

}

@Override

public int getCount() {

return sNewsList.size();

}

@Override

public Object getItem(int position) {

return sNewsList.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

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

Holder h = null;

if (convertView == null) {

h = new Holder();

convertView = mInflater.inflate(R.layout.list_item, null);

h.content = (TextView) convertView.findViewById(R.id.tv_content);

convertView.setTag(h);

} else {

h = (Holder) convertView.getTag();

}

h.content.setText(sNewsList.get(position));

return convertView;

}

private class Holder {

public TextView content;

}

}

}

(4).Activity的布局文件activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

xmlns:imglistview="http://schemas.android.com/apk/res/com.roger.listimgdemo"

android:layout_width="match_parent"

android:layout_height="match_parent" >

<com.roger.listimgdemo.ImgListView

android:id="@+id/xListView"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_margin="0dp"

android:cacheColorHint="#00000000"

android:divider="#ffffff"

android:dividerHeight="0dp"

android:fadingEdgeLength="0dp"

android:padding="0dp"

imglistview:headimage="@drawable/top_img" />

</RelativeLayout>

(5).Adapter的布局文件list_item.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_marginLeft="5dp"

android:layout_marginRight="5dp"

android:background="#EEEEEE"

android:orientation="horizontal" >

<TextView

android:id="@+id/tv_content"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginBottom="5dp"

android:layout_marginLeft="5dp"

android:layout_marginTop="25dp"

android:padding="10dp"

android:text="1"

android:textColor="#000000"

android:textIsSelectable="false" />

</LinearLayout>