前言
最近几天工作不忙,给伙伴们推荐两款UI。
效果图:
#仿IOS复制代码
1.导入jar
compile 'com.mylhyl:circleDialog:2.1.6'
2.布局activity_main.xml复制代码
<Button
android:id="@+id/button"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_marginTop="100dp"
android:layout_centerHorizontal="true"
android:text="点击特效" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#f00"
android:text="按项目名称"
android:textSize="20sp" />复制代码
实现代码:
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// new CircleDialog.Builder(MainActivity.this)
// .setTitle("标题")
// .setText("确定要退出")
// .setPositive("确定", null)
// .show();
final String[] items = {"拍照", "从相册选择", "小视频"};
new CircleDialog.Builder(MainActivity.this)
.configDialog(new ConfigDialog() {
@Override
public void onConfig(DialogParams params) {
//增加弹出动画
// params.animStyle = R.style.dialogWindowAnim;
}
})
.setTitle("标题")
.setTitleColor(Color.BLUE)
.setItems(items, new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this,items[position],Toast.LENGTH_SHORT).show();
}
})
.setNegative("取消", null)
.configNegative(new ConfigButton() {
@Override
public void onConfig(ButtonParams params) {
//取消按钮字体颜色
params.textColor = Color.RED;
}
})
.show();
}
});复制代码
就这样就轻松实现,是不是很简单方便。
特别注意,这里面有一个坑点,如果使用CircleDialog的话,就是需要在AndroidManifest.xml中做配置
<meta-data android:name="design_width" android:value="1200"/>
<meta-data android:name="design_height" android:value="1920"/>
只有这样才可以显示弹框,这里与AutoLayout使用很像 复制代码
#自定义
#废话不多说,直接上代码复制代码
1.定义item_hint_popupwindow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#e6e6e6" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="#333"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="aaaaaaaa"
android:layout_gravity="center"/>
</LinearLayout>复制代码
2.定义item_root_hintpopupwindow.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#66333333"/>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="10dp"
android:background="@drawable/bg2" />复制代码
3.在drawable中添加 .9图
4.创建一个java类
public class HintPopupWindow {
private Activity activity;
private WindowManager.LayoutParams params;
private boolean isShow;
private WindowManager windowManager;
private ViewGroup rootView;
private ViewGroup linearLayout;
private final int animDuration = 250;//动画执行时间
private boolean isAniming;//动画是否在执行
private TextView mianText;
/**
* @param contentList 点击item的内容文字
* @param clickList 点击item的事件
* 文字和click事件的list是对应绑定的
*/
public HintPopupWindow(Activity activity, List<String> contentList, List<View.OnClickListener> clickList,setOnClickListener listener){
this.activity = activity;
windowManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
initLayout(contentList, clickList,listener);
}
/**
* @param contentList 点击item内容的文字
* @param clickList 点击item的事件
* @setOnClickListener listener
*/
public void initLayout(final List<String> contentList, List<View.OnClickListener> clickList,final setOnClickListener listener){
//这是根布局
rootView = (ViewGroup) View.inflate(activity, R.layout.item_root_hintpopupwindow, null);
linearLayout = (ViewGroup) rootView.findViewById(R.id.linearLayout);
//格式化点击item, 将文字和click事件一一绑定上去
final List<View> list = new ArrayList<>();
for(int x=0; x<contentList.size(); x++){
View view = View.inflate(activity, R.layout.item_hint_popupwindow, null);
TextView textView = (TextView) view.findViewById(R.id.tv_content);
View v_line = view.findViewById(R.id.v_line);
textView.setText(contentList.get(x));
final int finalX = x;
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissPopupWindow();
listener.OnClickListener(finalX);
mianText.setText(contentList.get(finalX));
Toast.makeText(activity,"="+contentList.get(finalX),Toast.LENGTH_SHORT).show();
}
});
linearLayout.addView(view);
list.add(view);
if(x == 0){
v_line.setVisibility(View.INVISIBLE);
}else{
v_line.setVisibility(View.VISIBLE);
}
}
for (int x=0; x<list.size(); x++){
list.get(x).setOnClickListener(clickList.get(x));
}
//这里给你根布局设置背景透明, 为的是让他看起来和activity的布局一样
params = new WindowManager.LayoutParams();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.format = PixelFormat.RGBA_8888;//背景透明
params.gravity = Gravity.LEFT | Gravity.TOP;
//当点击根布局时, 隐藏
rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismissPopupWindow();
}
});
rootView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
//如果是显示状态那么隐藏视图
if(keyCode == KeyEvent.KEYCODE_BACK && isShow) dismissPopupWindow();
return isShow;
}
});
}
public void setData(TextView textView){
this.mianText = textView;
}
/**
* 弹出选项弹窗
* @param locationView 默认在该view的下方弹出, 和popupWindow类似
*/
public void showPopupWindow(View locationView){
Log.i("Log.i", "showPopupWindow: "+isAniming);
if(!isAniming) {
isAniming = true;
try {
//这个步骤是得到该view相对于屏幕的坐标, 注意不是相对于父布局哦!
int[] arr = new int[2];
locationView.getLocationOnScreen(arr);
linearLayout.measure(0, 0);
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);//得到状态栏高度
float x = arr[0] + locationView.getWidth() - linearLayout.getMeasuredWidth();
float y = arr[1] - frame.top + locationView.getHeight();
linearLayout.setX(x);
linearLayout.setY(y);
/*捕获当前activity的布局视图, 因为我们要动态模糊, 所以这个布局一定要是最新的,
*这样我们把模糊后的布局盖到屏幕上时, 才能让用户感觉不出来变化*/
View decorView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
Bitmap bitmap = getBitmapByView(decorView);//这里是将view转成bitmap
setBlurBackground(bitmap);//这里是模糊图片, 这个是重点我会单独讲的, 因为效率很重要啊!!!
//这里就是使用WindowManager直接将我们处理好的view添加到屏幕最前端
windowManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
windowManager.addView(rootView, params);
//这一步就是有回弹效果的弹出动画, 我用属性动画写的, 很简单
showAnim(linearLayout, 0, 1, animDuration, true);
//视图被弹出来时得到焦点, 否则就捕获不到Touch事件
rootView.setFocusable(true);
rootView.setFocusableInTouchMode(true);
rootView.requestFocus();
rootView.requestFocusFromTouch();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 得到bitmap位图, 传入View对象
*/
public static Bitmap getBitmapByView(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
view.draw(new Canvas(bitmap));
return bitmap;
}
private void setBlurBackground(Bitmap bitmap) {
rootView.setAlpha(0);
alphaAnim(rootView, 0, 1, animDuration);
}
public void dismissPopupWindow(){
Log.i("Log.i", "dismissPopupWindow: "+isAniming);
if(!isAniming) {
isAniming = true;
isShow = false;
goneAnim(linearLayout, 0.95f, 1, animDuration / 3, true);
}
}
public WindowManager.LayoutParams getLayoutParams(){
return params;
}
public ViewGroup getLayout(){
return linearLayout;
}
/**
* popupwindow是否是显示状态
*/
public boolean isShow(){
return isShow;
}
private void alphaAnim(final View view, int start, int end, int duration){
ValueAnimator va = ValueAnimator.ofFloat(start, end).setDuration(duration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
view.setAlpha(value);
}
});
va.start();
}
private void showAnim(final View view, float start, final float end, int duration, final boolean isWhile) {
ValueAnimator va = ValueAnimator.ofFloat(start, end).setDuration(duration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
view.setPivotX(view.getWidth());
view.setPivotY(0);
view.setScaleX(value);
view.setScaleY(value);
}
});
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (isWhile) {
showAnim(view, end, 0.95f, animDuration / 3, false);
}else{
isAniming = false;
}
}
});
va.start();
}
public void goneAnim(final View view, float start, final float end, int duration, final boolean isWhile){
ValueAnimator va = ValueAnimator.ofFloat(start, end).setDuration(duration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
view.setPivotX(view.getWidth());
view.setPivotY(0);
view.setScaleX(value);
view.setScaleY(value);
}
});
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if(isWhile){
alphaAnim(rootView, 1, 0, animDuration);
goneAnim(view, end, 0f, animDuration, false);
}else{
try {
windowManager.removeViewImmediate(rootView);
}catch (Exception e){
e.printStackTrace();
}
isAniming = false;
}
}
});
va.start();
}复制代码
4.定义一个interface 回调点击的数据
public interface setOnClickListener {
void OnClickListener(int finalX);
}复制代码
5.在MainActivity中直接使用
public class MainActivity extends AppCompatActivity {
private HintPopupWindow hintPopupWindow;
private TextView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (TextView) findViewById(R.id.textView);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//弹出选项弹窗
hintPopupWindow.showPopupWindow(v);
hintPopupWindow.setData(imageView);
}
});
//初始化弹出数据
ArrayList<String> strList = new ArrayList<>();
strList.add("选项item1");
strList.add("选项item2");
strList.add("选项item3");
ArrayList<View.OnClickListener> clickList = new ArrayList<>();
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// Toast.makeText(MainActivity.this, "点击事件触发", Toast.LENGTH_SHORT).show();
}
};
clickList.add(clickListener);
clickList.add(clickListener);
clickList.add(clickListener);
//具体初始化
hintPopupWindow = new HintPopupWindow(this, strList, clickList, new setOnClickListener() {
@Override
public void OnClickListener(int finalX) {
int tag = finalX+1;
Log.e("tag","=====finalX===下标====="+tag);
}
});
}
}复制代码
#总结
由于简单,项目地址就不发链接,大家按照步骤就可以实现。希望对各位有所帮助。如果有问题,欢迎大家评论