PopupWindow、dialog怜械,DialogFragment厂汗。
比如說需求:
只攔截自身所占空間部分的事件元莫,其余空間的點擊事件不處理
可以根據(jù)改變View的布局排列方式,View是否設置底部背景及居中方式
雖然在功能上 PopupWindow 更符合需要框杜,dialog也能做到浦楣,但是使用 DialogFragment 代碼更簡潔、更方便封裝功能模塊咪辱。
基于Fragment的DialogFragment振劳,便于自定義UI,在生命周期上也優(yōu)于其他兩個油狂,性能上也是历恐。
從代碼的編寫角度看寸癌,Dialog使用起來要更為簡單
Android 官方推薦使用 DialogFragment 來代替 Dialog ,可以讓它具有更高的可復用性(降低耦合)和更好的便利性(很好的處理屏幕翻轉(zhuǎn)的情況)弱贼。
DialogFragment果然有一個非常好的特性(在手機配置變化蒸苇,導致Activity需要重新創(chuàng)建時,例如旋屏哮洽,基于DialogFragment的對話框?qū)蒄ragmentManager自動重建填渠,然而基于Dialog實現(xiàn)的對話框則沒有這樣的能力)。
創(chuàng)建:創(chuàng)建 DialogFragment 有兩種方式:
覆寫其 onCreateDialog 方法
*應用場景*:一般用于創(chuàng)建替代傳統(tǒng)的 Dialog 對話框的場景鸟辅,UI 簡單氛什,功能單一。
覆寫其 onCreateView 方法
*應用場景*:一般用于創(chuàng)建復雜內(nèi)容彈窗或全屏展示效果的場景匪凉,UI 復雜枪眉,功能復雜,一般有網(wǎng)絡請求等異步操作再层。
示例:
public class HotKeyDialogFragment extends DialogFragment implements Constants, View.OnFocusChangeListener, View.OnClickListener {
public static final String TAG? ? ? ? ? ? ? ? =HotKeyDialogFragment.class.getSimpleName();
? private View? ? ? ? ? ? mView? ? ? ? ? =null;
? private ImageView? ? ? ? mIvSearch? ? ? ? =null;
? private ImageView? ? ? ? mIvCollection? ? =null;
? private ImageView? ? ? ? mIvHistory? ? ? =null;
? private ImageView? ? ? ? mIvAbout? ? ? ? =null;
? private SimpleDraweeView? mImageView? ? ? =null;
? private int? ? ? ? ? ? ? ? mCurrentPosition? = -1;
? public static HotKeyDialogFragment newInstance() {
HotKeyDialogFragment dialog =new HotKeyDialogFragment();
? ? ? return dialog;
? }
@Override
? public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
? ? ? setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Dialog);
? }
@Override
? public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.hot_key_fragment_dialog, null);
? ? ? setLocation();
? ? ? initData();
? ? ? mIvSearch =mView.findViewById(R.id.iv_search);
? ? ? mIvSearch.setFocusable(true);
? ? ? mIvSearch.requestFocus();
? ? ? if (mIvSearch.hasFocus()) {
mIvSearch.setImageResource(R.mipmap.bottom_popup_search_sel);
? ? ? }
mIvCollection =mView.findViewById(R.id.iv_collection);
? ? ? mIvHistory =mView.findViewById(R.id.iv_history);
? ? ? mIvAbout =mView.findViewById(R.id.iv_about);
? ? ? mImageView =mView.findViewById(R.id.iv_app_er_code);
? ? ? mImageView.setAspectRatio(1);
? ? ? mImageView.setImageResource(R.mipmap.er_code_image);
? ? ? setListener();
? ? ? return mView;
? }
@Override
? public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
? }
private void setListener() {
mIvSearch.setOnFocusChangeListener(this);
? ? ? mIvCollection.setOnFocusChangeListener(this);
? ? ? mIvHistory.setOnFocusChangeListener(this);
? ? ? mIvAbout.setOnFocusChangeListener(this);
? ? ? mIvSearch.setOnClickListener(this);
? ? ? mIvCollection.setOnClickListener(this);
? ? ? mIvHistory.setOnClickListener(this);
? ? ? mIvAbout.setOnClickListener(this);
? }
private void setLocation() {
Window window =getDialog().getWindow();
? ? ? window.setGravity(Gravity.CENTER_HORIZONTAL |Gravity.BOTTOM);
? ? ? window.getAttributes().windowAnimations =R.style.dialogAnim;
? }
@Override
? public void show(FragmentManager manager, String tag) {
try {
manager.beginTransaction().remove(this).commit();
? ? ? ? super.show(manager, tag);
? ? ? }catch (IllegalStateException ignore) {
}
}
@Override
? public void onFocusChange(View view, boolean hasFocus) {
switch (view.getId()) {
case R.id.iv_search:
if (hasFocus) {
mIvSearch.setImageResource(R.mipmap.bottom_popup_search_sel);
? ? ? ? ? ? }else {
mIvSearch.setImageResource(R.mipmap.bottom_popup_search);
? ? ? ? ? ? }
break;
? ? ? ? case R.id.iv_collection:
if (hasFocus) {
mIvCollection.setImageResource(R.mipmap.bottom_popup_collection_sel);
? ? ? ? ? ? }else {
mIvCollection.setImageResource(R.mipmap.bottom_popup_collection);
? ? ? ? ? ? }
break;
? ? ? ? case R.id.iv_history:
if (hasFocus) {
mIvHistory.setImageResource(R.mipmap.bottom_popup_history_sel);
? ? ? ? ? ? }else {
mIvHistory.setImageResource(R.mipmap.bottom_popup_history);
? ? ? ? ? ? }
break;
? ? ? ? case R.id.iv_about:
if (hasFocus) {
mIvAbout.setImageResource(R.mipmap.bottom_popup_about_sel);
? ? ? ? ? ? }else {
mIvAbout.setImageResource(R.mipmap.bottom_popup_about);
? ? ? ? ? ? }
break;
? ? ? ? default:
break;
? ? ? }
}
@Override
? public void onResume() {
super.onResume();
? ? ? switch (mCurrentPosition){
case 0:
mIvSearch.setFocusable(true);
? ? ? ? ? ? mIvSearch.requestFocus();
? ? ? ? ? ? if (mIvSearch.hasFocus()) {
mIvSearch.setImageResource(R.mipmap.bottom_popup_search_sel);
? ? ? ? ? ? }
break;
? ? ? ? case 1:
mIvCollection.setFocusable(true);
? ? ? ? ? ? mIvCollection.requestFocus();
? ? ? ? ? ? if (mIvCollection.hasFocus()) {
mIvCollection.setImageResource(R.mipmap.bottom_popup_collection_sel);
? ? ? ? ? ? }
break;
? ? ? ? case 2:
mIvHistory.setFocusable(true);
? ? ? ? ? ? mIvHistory.requestFocus();
? ? ? ? ? ? if (mIvHistory.hasFocus()) {
mIvHistory.setImageResource(R.mipmap.bottom_popup_history_sel);
? ? ? ? ? ? }
break;
? ? ? ? case 3:
mIvAbout.setFocusable(true);
? ? ? ? ? ? mIvAbout.requestFocus();
? ? ? ? ? ? if (mIvAbout.hasFocus()) {
mIvAbout.setImageResource(R.mipmap.bottom_popup_about_sel);
? ? ? ? ? ? }
break;
? ? ? ? default:
break;
? ? ? }
}
@Override
? public void onClick(View view) {
switch (view.getId()){
case R.id.iv_search:
mCurrentPosition=0;
? ? ? ? ? ? if (getActivity()instanceof SearchActivity) {
this.dismiss();
? ? ? ? ? ? ? return;
? ? ? ? ? ? }else {
if (getActivity()instanceof MainActivity||getActivity()instanceof BookSecondActivity){
Intent intent =new Intent(getActivity(), SearchActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }else {
getActivity().finish();
? ? ? ? ? ? ? ? ? Intent intent =new Intent(getActivity(), SearchActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }
}
break;
? ? ? ? case R.id.iv_collection:
mCurrentPosition=1;
? ? ? ? ? ? if (getActivity()instanceof CollectionActivity) {
this.dismiss();
? ? ? ? ? ? ? return;
? ? ? ? ? ? }else {
if (getActivity()instanceof MainActivity||getActivity()instanceof BookSecondActivity){
Intent intent =new Intent(getActivity(), CollectionActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }else {
getActivity().finish();
? ? ? ? ? ? ? ? ? Intent intent =new Intent(getActivity(), CollectionActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }
}
break;
? ? ? ? case R.id.iv_history:
mCurrentPosition=2;
? ? ? ? ? ? if (getActivity()instanceof HistoryActivity) {
this.dismiss();
? ? ? ? ? ? ? return;
? ? ? ? ? ? }else {
if (getActivity()instanceof MainActivity||getActivity()instanceof BookSecondActivity){
Intent intent =new Intent(getActivity(), HistoryActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }else {
getActivity().finish();
? ? ? ? ? ? ? ? ? Intent intent =new Intent(getActivity(), HistoryActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }
}
break;
? ? ? ? case R.id.iv_about:
mCurrentPosition=3;
? ? ? ? ? ? if (getActivity()instanceof AboutActivity) {
this.dismiss();
? ? ? ? ? ? ? return;
? ? ? ? ? ? }else {
if (getActivity()instanceof MainActivity||getActivity()instanceof BookSecondActivity){
Intent intent =new Intent(getActivity(), AboutActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }else {
getActivity().finish();
? ? ? ? ? ? ? ? ? Intent intent =new Intent(getActivity(), AboutActivity.class);
? ? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? ? }
}
break;
? ? ? ? default:
break;
? ? ? }
}
@Override
? public void onDestroy() {
super.onDestroy();
? }
}
以上示例是我在項目里面的一個小功能應用在TV端的贸铜,需要注意的是DialogFragment在show的時候,最好是自已重寫show方法聂受,因為DialogFrament是繼承自Fragment的蒿秦,他本身的show方法其實是調(diào)用了Fragment的commit方法,這樣在重復打開的時候容易有問題蛋济,
@Override
?? public void show(FragmentManager manager, String tag) {
try {
manager.beginTransaction().remove(this).commit();
? ? ? ?? super.show(manager, tag);
? ? ? }catch (IllegalStateException ignore) {
}
}
這樣重寫show方法每次show的時候把前一次commit移除掉棍鳖,有效的避免了重復commit引起的bug.另外還需要注意dialogFrament設置大小和位置的辦法,如果有具體的背景圖就不需要在代碼里面手動設置大小碗旅,在xml文件里面設置wrap_content就可以渡处,但是位置需要通過window手動設置,彈框動畫也是直接設置window的stytle去設置祟辟。
以上是我個人使用的一點小總結医瘫,謝謝瀏覽。