前言
最近幾天工作不忙,給夥伴們推薦兩款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);
}
});
}
}複製程式碼
#總結
由於簡單,專案地址就不發連結,大家按照步驟就可以實現。希望對各位有所幫助。如果有問題,歡迎大家評論