您的位置:首页 > 移动开发 > Android开发

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

2017-06-20 18:20 211 查看


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

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



2.具体实现步骤



代码结构图
(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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息