最近项目上要求在listview上实现类似ios 3dTouch功能,现在网上搜索一番,发现该文章很好的实现了这个功能,于是在这文章的基础上我自己做了一个改进。效果如图所示:
实现思路:
思路:布局的时候下面一张高斯模糊的图片,上面高斯模糊的图片,对上面的图片进行动态透明度变化,这时候看效果就是动态高斯模糊了
4.在按压位置出现一个新的控件浮在上面
思路:动态添加view,通过计算点击位置获取listview的item位置,给该view设置setMargins控制其位置
5.优化
代码:
Activity文件
1.截取图片
// 获取屏幕照片
public static Bitmap captureScreen(Activity activity) {
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
Bitmap bmp = activity.getWindow().getDecorView().getDrawingCache();
return bmp;
}
2.做高斯模糊处理
// 高斯模糊处理
private Bitmap blur(Bitmap bitmap, float radius) {
Bitmap output = Bitmap.createBitmap(bitmap); // 创建输出图片
RenderScript rs = RenderScript.create(this); // 构建一个RenderScript对象
ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
// 创建高斯模糊脚本
Allocation allIn = Allocation.createFromBitmap(rs, bitmap); // 开辟输入内存
Allocation allOut = Allocation.createFromBitmap(rs, output); // 开辟输出内存
gaussianBlue.setRadius(radius); // 设置模糊半径,范围0f<radius<=25f
gaussianBlue.setInput(allIn); // 设置输入内存
gaussianBlue.forEach(allOut); // 模糊编码,并将内存填入输出内存
allOut.copyTo(output); // 将输出内存编码为Bitmap,图片大小必须注意
rs.destroy(); // 关闭RenderScript对象,API>=23则使用rs.releaseAllContexts()
return output;
}
3.按压实现动态高斯模糊
思路:布局的时候下面一张高斯模糊的图片,上面高斯模糊的图片,对上面的图片进行动态透明度变化,这时候看效果就是动态高斯模糊了
4.在按压位置出现一个新的控件浮在上面
思路:动态添加view,通过计算点击位置获取listview的item位置,给该view设置setMargins控制其位置
5.优化
代码:
xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/test_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
<ImageView
android:id="@+id/image_down"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="@+id/image_up"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<TextView
android:id="@+id/item_tv_ss"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="30sp"
android:background="#ffffff"
/>
</RelativeLayout>
Activity文件
package memorandum.ios.csc.com.memorandum.activity;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import memorandum.ios.csc.com.memorandum.R;
/**
* Created by csc on 17-7-31.
*/
public class TestActivity extends Activity{
private ListView testListView;
private List<Map<String, String>> data;
private ImageView imageUp, imageDown;
private Bitmap sampleImg;
private Bitmap gaussianBlurImg;
private int count = 0;
private View attachedView;
private RelativeLayout rootRl;
private TextView testTv;
RelativeLayout.LayoutParams lp;
private boolean is3DTouch = false;
@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.test);
initData();
imageUp = (ImageView) findViewById(R.id.image_up);
imageDown = (ImageView) findViewById(R.id.image_down);
testListView = (ListView) findViewById(R.id.test_list);
testListView.setAdapter(new SimpleAdapter(this, data, R.layout.listview_item, new String[]{"name"},
new int[]{R.id.item_tv}));
attachedView = View.inflate(this,R.layout.listview_item,null);
rootRl = (RelativeLayout) findViewById(R.id.root);
testTv = (TextView)findViewById(R.id.item_tv_ss);
lp = new RelativeLayout.LayoutParams(testTv.getLayoutParams());
testListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
count = 0;
sampleImg = captureScreen(TestActivity.this);
imageUp.setVisibility(View.VISIBLE);
imageDown.setVisibility(View.VISIBLE);
imageUp.setImageBitmap(sampleImg);
gaussianBlurImg = blur(sampleImg, 25f);// 高斯模糊图片
imageDown.setImageBitmap(gaussianBlurImg);
imageUp.setImageAlpha(255);
HashMap item = (HashMap)testListView.getItemAtPosition(i);
String section =String.valueOf(item.get("name").toString());//get每一行的数据的名字
testTv.setText(section);
int[] location = new int[2] ;
testListView.getChildAt(i-testListView.getFirstVisiblePosition()).getLocationOnScreen(location);
lp.setMargins(0, location[1], 0, 0);
testTv.setLayoutParams(lp);
testTv.setVisibility(View.VISIBLE);
is3DTouch = true;
return false;
}
});
testListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
if(is3DTouch){
if (count < 255)
count = count + 8;
int alpha = 255 - count;
if (alpha < 0)
alpha = 0;
imageUp.setImageAlpha(alpha);
}
break;
case MotionEvent.ACTION_UP:
if(is3DTouch){
imageUp.setImageAlpha(255);
testTv.setVisibility(View.GONE);
imageUp.setVisibility(View.GONE);
imageDown.setVisibility(View.GONE);
is3DTouch = false;
}
break;
}
return false;
}
});
}
private void initData() {
data = new ArrayList<Map<String, String>>();
for (int i = 0; i < 20; i++) {
Map<String, String> map = new HashMap<String, String>();
map.put("name", "BYXD" + i);
data.add(map);
}
}
// 高斯模糊处理
private Bitmap blur(Bitmap bitmap, float radius) {
Bitmap output = Bitmap.createBitmap(bitmap); // 创建输出图片
RenderScript rs = RenderScript.create(this); // 构建一个RenderScript对象
ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
// 创建高斯模糊脚本
Allocation allIn = Allocation.createFromBitmap(rs, bitmap); // 开辟输入内存
Allocation allOut = Allocation.createFromBitmap(rs, output); // 开辟输出内存
gaussianBlue.setRadius(radius); // 设置模糊半径,范围0f<radius<=25f
gaussianBlue.setInput(allIn); // 设置输入内存
gaussianBlue.forEach(allOut); // 模糊编码,并将内存填入输出内存
allOut.copyTo(output); // 将输出内存编码为Bitmap,图片大小必须注意
rs.destroy(); // 关闭RenderScript对象,API>=23则使用rs.releaseAllContexts()
return output;
}
// 获取屏幕照片
public static Bitmap captureScreen(Activity activity) {
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
Bitmap bmp = activity.getWindow().getDecorView().getDrawingCache();
return bmp;
}
}
到这里就实现了listview动态高斯模糊效果了。接下来对代码进行优化,将效果调到iphone通讯录那样,在该效果后面加个popupmenu,这个有空贴代码。