仿一个美团的效果

最近在技术群里面看到有人发了一个很炫酷的效果gif图,然后再问实现的方法,看了一下效果然后自己写了一个小demo

先上人家的原图效果:


下面上我模仿的gif图,效果没有全部模仿完,界面很粗糙,只模仿效果



如下是实现代码:

package com.test.mteffect;

import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.RenderScript;
import android.support.v8.renderscript.ScriptIntrinsicBlur;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.view.animation.Transformation;
import android.view.animation.Animation.AnimationListener;
import android.widget.LinearLayout.LayoutParams;

public class MainActivity extends Activity {

	private View bg_ll_flur;
	private View bg_ll_bg;
	private ImageView mt_flur_btnimg;
	private LinearLayout mt_flur_ll;
	private ListView mt_flur_lvm;
	private ListView mt_flur_lv;

	private static int HEADHEIGHT = 0;
	private boolean expandable = false;
	private MtAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		bg_ll_flur = this.findViewById(R.id.bg_ll_flur);
		bg_ll_bg = this.findViewById(R.id.bg_ll_bg);
		mt_flur_btnimg = (ImageView) this.findViewById(R.id.mt_flur_btnimg);
		mt_flur_ll = (LinearLayout) this.findViewById(R.id.mt_flur_ll);
		mt_flur_lvm = (ListView) this.findViewById(R.id.mt_flur_lvm);
		mt_flur_lv = (ListView) this.findViewById(R.id.mt_flur_lv);

		initView();
	}

	private void initView() {
		mt_flur_lvm.setAdapter(new LMtAdapter());
		adapter = new MtAdapter();
		mt_flur_lv.setAdapter(adapter);
		mt_flur_btnimg.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (expandable) {
					collapse(mt_flur_ll);
				} else {
					expand(mt_flur_ll);
				}
			}
		});
	}

	private void applyBlur() {
		bg_ll_flur.getViewTreeObserver().addOnPreDrawListener(
				new ViewTreeObserver.OnPreDrawListener() {
					@Override
					public boolean onPreDraw() {
						bg_ll_flur.getViewTreeObserver()
								.removeOnPreDrawListener(this);
						bg_ll_flur.buildDrawingCache();

						Bitmap bmp = bg_ll_flur.getDrawingCache();
						blurRS(bmp, bg_ll_bg);
						return true;
					}
				});
	}

	/**
	 * 根据图片压缩放大模糊原理 效果较差,但能够兼容2.3+
	 * 
	 * @param bkg
	 * @param view
	 */
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
	private void blur(Bitmap bkg, View view) {
		float scaleFactor = 1;
		float radius = 20;

		// ====快速模糊
		scaleFactor = 8;
		radius = 2;
		// ====

		Bitmap overlay = Bitmap.createBitmap(
				(int) (view.getMeasuredWidth() / scaleFactor),
				(int) (view.getMeasuredHeight() / scaleFactor),
				Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(overlay);
		canvas.translate(-view.getLeft() / scaleFactor, -view.getTop()
				/ scaleFactor);
		canvas.scale(1 / scaleFactor, 1 / scaleFactor);
		Paint paint = new Paint();
		paint.setFlags(Paint.FILTER_BITMAP_FLAG);
		canvas.drawBitmap(bkg, 0, 0, paint);

		overlay = FastBlur.doBlur(overlay, (int) radius, true);
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
			view.setBackground(new BitmapDrawable(getResources(), overlay));
		} else {
			view.setBackgroundDrawable(new BitmapDrawable(getResources(),
					overlay));
		}
	}

	/**
	 * 根据Android自己的兼容包,如果使用系统自带的需要4.4+,使用V8兼容包,能够兼容4.2+
	 * 
	 * @param bkg
	 * @param view
	 */
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
	private void blurRS(Bitmap bkg, View view) {
		float scaleFactor = 1;
		float radius = 20;

		// ====快速模糊
		scaleFactor = 8;
		radius = 2;
		// ====

		Bitmap overlay = Bitmap.createBitmap(
				(int) (view.getMeasuredWidth() / scaleFactor),
				(int) (view.getMeasuredHeight() / scaleFactor),
				Bitmap.Config.ARGB_8888);

		Canvas canvas = new Canvas(overlay);

		canvas.translate(-view.getLeft() / scaleFactor, -view.getTop()
				/ scaleFactor);
		canvas.scale(1 / scaleFactor, 1 / scaleFactor);
		Paint paint = new Paint();
		paint.setFlags(Paint.FILTER_BITMAP_FLAG);
		canvas.drawBitmap(bkg, 0, 0, paint);

		RenderScript rs = RenderScript.create(getApplicationContext());

		Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);

		ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs,
				overlayAlloc.getElement());

		blur.setInput(overlayAlloc);

		blur.setRadius(radius);

		blur.forEach(overlayAlloc);

		overlayAlloc.copyTo(overlay);
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
			view.setBackground(new BitmapDrawable(getResources(), overlay));
		} else {
			view.setBackgroundDrawable(new BitmapDrawable(getResources(),
					overlay));
		}
		rs.destroy();
	}

	public void expand(final View v) {
		if (adapter.getCount() > 4) {
			HEADHEIGHT = dip2px(4 * 50 + 30 + 70 + 10);
		} else {
			HEADHEIGHT = dip2px(adapter.getCount() * 50 + 30 + 70);
		}
		v.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		final int targtetHeight = HEADHEIGHT;
		v.getLayoutParams().height = 0;
		v.setVisibility(View.VISIBLE);
		Animation a = new Animation() {
			@Override
			protected void applyTransformation(float interpolatedTime,
					Transformation t) {
				v.getLayoutParams().height = interpolatedTime == 1 ? targtetHeight
						: (int) (targtetHeight * interpolatedTime);
				v.requestLayout();
			}

			@Override
			public boolean willChangeBounds() {
				return true;
			}
		};
		a.setDuration(150);
		v.startAnimation(a);
		a.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {
				bg_ll_flur.setVisibility(View.INVISIBLE);
				bg_ll_bg.setVisibility(View.VISIBLE);
				applyBlur();
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				expandable = true;
			}
		});
	}

	public void collapse(final View v) {
		final int initialHeight = v.getMeasuredHeight();
		if (initialHeight > HEADHEIGHT) {
			HEADHEIGHT = initialHeight;
		}
		Animation a = new Animation() {
			@Override
			protected void applyTransformation(float interpolatedTime,
					Transformation t) {
				if (interpolatedTime == 1) {
					v.setVisibility(View.GONE);
				} else {
					v.getLayoutParams().height = initialHeight
							- (int) (initialHeight * interpolatedTime);
					v.requestLayout();
				}
			}

			@Override
			public boolean willChangeBounds() {
				return true;
			}
		};
		a.setDuration(150);
		v.startAnimation(a);
		a.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {
				bg_ll_flur.setVisibility(View.VISIBLE);
				bg_ll_bg.setVisibility(View.GONE);
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				expandable = false;
			}
		});
	}

	private class LMtAdapter extends BaseAdapter {

		private ViewHolder holder;

		@Override
		public int getCount() {
			return 15;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

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

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(getApplicationContext())
						.inflate(R.layout.mm_item, parent, false);
				holder = new ViewHolder(convertView);
			}

			switch (position % 3) {
			case 0:
				holder.img.setImageResource(R.drawable.ter);
				break;

			case 1:
				holder.img.setImageResource(R.drawable.sfas);
				break;

			case 2:
				holder.img.setImageResource(R.drawable.swq);
				break;

			default:
				holder.img.setImageResource(R.drawable.swq);
				break;
			}
			return convertView;
		}

		class ViewHolder {
			private ImageView img;

			ViewHolder(View view) {
				img = (ImageView) view.findViewById(R.id.mm_img);
			}
		}
	}

	private class MtAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return 5;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

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

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(getApplicationContext())
						.inflate(R.layout.mt_item, parent, false);
			}
			return convertView;
		}
	}

	public int dip2px(float dipValue) {
		final float scale = getResources().getDisplayMetrics().density;
		return (int) (dipValue * scale + 0.5f);
	}
}

文件地址:http://download.csdn.net/detail/u011566000/8461209


猜你喜欢

转载自blog.csdn.net/u011566000/article/details/43968679
今日推荐