DialogFragment
比Dialog優勢,具有生命週期,比如旋轉屏幕的時候,activity重建,dialog就不會重新創建,由於不是正常銷燬的,會造成內存泄漏,而DialogFragment會隨着activity的銷燬正常銷燬,並且旋轉屏幕後也會重建
使用方法:
- 如果已經有存在的dialog 就重寫onCreateDialog方法,創建已經存在的dialog
- 重寫onCreateView直接創建,跟fragment創建一樣
但是需要setStyle
1 全屏的DialogFragment
public class DialogFragmentFullScreen extends DialogFragment implements DialogInterface.OnKeyListener {
private DialogFragmentDismissListener mDialogFragmentDismissListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(Window.FEATURE_NO_TITLE, R.style.DialogFragmentFullScreen);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getDialog().setOnKeyListener(this);
}
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
// 如果需要動畫或處理返回鍵操作需要重寫dismiss方法
if (isCancelable() && keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
finish();
return true;
}
return false;
}
protected void finish() {
dismiss();
}
public void show(FragmentManager fragmentManager) {
this.show(fragmentManager, this.getClass().getSimpleName());
}
public void setDialogFragmentDismissListener(DialogFragmentDismissListener dialogFragmentDismissListener) {
mDialogFragmentDismissListener = dialogFragmentDismissListener;
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (mDialogFragmentDismissListener != null) {
mDialogFragmentDismissListener.onDismiss();
}
}
}
非全屏DialogFragment
public class DialogFragmentUnFullScreen extends DialogFragmentFullScreen {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(Window.FEATURE_NO_TITLE, R.style.DialogFragmentUnFullScreen);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Window window = getDialog().getWindow();
if (window != null) {
window.setLayout(getWidth(), WindowManager.LayoutParams.WRAP_CONTENT); //必須手動指定寬高,佈局寫死100dp也是不起作用的
}
}
protected int getWidth() {
return AppUtils.dp2px(280, getResources().getDisplayMetrics());
}
}
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textAllCaps">false</item>
</style>
<style name="DialogFragmentFullScreen" parent="AppTheme">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:windowBackground">@color/dialog_alpha_bg</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation</item>
<item name="colorPrimaryDark">@color/transparent</item>
</style>
<style name="DialogFragmentUnFullScreen" parent="@style/Theme.AppCompat.Light.Dialog">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsTranslucent">true</item>
</style>
</resources>
PopWindow 嵌套ListView
我寫該popWindow工具類主要是項目中如果用到多次的話,將其封裝,每次都能直接使用,比較方便,而且格式能夠統一
1.首先是佈局文件,比較簡單,就一個ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/pop_back"
>
<ListView
android:id="@+id/pop_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/light_gray"
android:dividerHeight="1px"
android:listSelector="@color/transparent"
android:scrollbars="none"
/>
</LinearLayout>
2.其次是ListView裏面需要用的Java Bean
public class PopStringItem {
private String id;
private int icon;
private String name;
public PopStringItem(String id,int icon, String name) {
this.id = id;
this.icon = icon;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
}
3.然後是popWindow的實現代碼
public class ListPopWindow extends PopupWindow implements View.OnKeyListener {
private List<PopStringItem> itemList;
private LayoutInflater inflater;
private PopListItemClickListener listItemClickListener;
private Window window;
private final WindowManager.LayoutParams params;
public ListPopWindow(Context context, List<PopStringItem> items, PopListItemClickListener listItemClickListener) {
super(context);
init(context);
window = ((Activity) context).getWindow();
params = window.getAttributes();
this.itemList = items;
this.listItemClickListener = listItemClickListener;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.list_pop_window, null);
setContentView(view);
ListView listView = (ListView) view.findViewById(R.id.pop_list);
if (items.size() == 1) {
listView.setDividerHeight(0);
}
MyAdapter adapter = new MyAdapter();
listView.setAdapter(adapter);
listView.setOnKeyListener(this);
listView.setOnItemClickListener(adapter);
}
private void init(Context context) {
int w = context.getResources().getDisplayMetrics().widthPixels;
setWidth(w / 3); //需要顯示設置寬高度
setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
setFocusable(true);//設置popWindow是否具有獲取焦點的能力,默認爲false,一般來講作用不大,但如果裏面包含EditText等需要獲取焦點的控件必須設置爲true
setOutsideTouchable(true);//設置點擊外部區域popWindow是否會消失
setBackgroundDrawable(new BitmapDrawable()); //設置popWindow的背景,只有加了該屬性之後,setOutsideTouchable纔會起作用,而且加了它之後,popWindow對手機的返回鍵纔有響應,點擊返回按鈕,關閉popWindow,否則就會關閉popWindow所在的Activity
update();
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
dismiss();
return true;
}
@Override
public void showAsDropDown(View anchor) {
params.alpha = 0.5f; //如果popWindow顯示的時候想讓window背景變透明,就需要這樣做
window.setAttributes(params);
super.showAsDropDown(anchor);
}
@Override
public void showAsDropDown(View anchor, int xoff, int yoff) {
params.alpha = 0.5f;
window.setAttributes(params);
super.showAsDropDown(anchor, xoff, yoff);
}
@Override
public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
params.alpha = 0.5f;
window.setAttributes(params);
super.showAsDropDown(anchor, xoff, yoff, gravity);
}
@Override
public void dismiss() {
params.alpha = 1f; //設置回來
window.setAttributes(params);
super.dismiss();
}
class MyAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {
@Override
public int getCount() {
int ret = 0;
if (itemList != null) {
ret = itemList.size();
}
return ret;
}
@Override
public PopStringItem getItem(int position) {
return itemList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
PopStringItem item = getItem(position);
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_pop_list, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.image);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
int icon = item.getIcon();
if (icon == 0) {
holder.image.setVisibility(View.GONE);
} else {
holder.image.setVisibility(View.VISIBLE);
holder.image.setImageResource(icon);
}
holder.text.setText(item.getName());
return convertView;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PopStringItem item = getItem(position);
if (listItemClickListener != null) {
listItemClickListener.onClick(item);
}
}
class ViewHolder {
ImageView image;
TextView text;
}
}
//一個回調接口,交給使用PopWindow的Activity來處理
public interface PopListItemClickListener {
void onClick(PopStringItem item);
}
}
4.popWindow的使用
//顯示
if (popupWindow == null) {
popupWindow = new ListPopWindow(context, items, this);//items要提前賦值,this表示該類實現上面的回調點擊事件
}
popupWindow.showAsDropDown();//需要設置參數
//點擊事件的回調
@Override
public void onClick(PopStringItem item) {
popupWindow.dismiss();
if (item.getId().equals("")) {
//根據id判斷點擊哪個item,進行事件處理
}
}