安卓 通用BaseDialog封装

一、学习准备

(1).会一点反射知识      可以看看我写的反射

(2).会一点注解知识 

(3).大致看下DialogFragment

(4).运行效果

 

 

二、代码部分

(1).注解代码

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})   /**用于描述类、接口(包括注解类型) 或enum声明 Class, interface (including annotation type), or enum declaration */
public @interface ActivityFragmentInject {

    /**
     * 布局Id
     */
    int contentViewId() default -1;

    /**
     * 是否开启EventBus
     */
    boolean isOpenEventBus() default false;
}

(2)BaseDialogFragment代码

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import com.ycb.basedialog.R;
import com.ycb.basedialog.annotation.ActivityFragmentInject;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * Created by asus on 2019/3/30.
 */
public abstract class BaseDialogFragment extends DialogFragment {
    /*
    *需要能自定义的功能
    * 1.可以设置dialog的宽高
    * 2.可以设置dialog的背景透明度
    * 3.可以设置dialog的显示位置
    * 4.可以设置dialog的外边距
    * 5.可以自定义dialog的布局
    * 6.可以设置dialog的进出动画
     */

     private int mMargin=0; //外边距
     private float mDimAmout=0.5f; //背景透明度
     private boolean  mShowBottomEnable=true;//是否显示底部
     private int mWidth,mHeight;//宽高
     private int mContentViewId;  //布局id
     private int mAnimStyle=0; //进出动画
     private boolean mOutCancel=true;//点击外部取消
     private Context mContext;
     private View mView;
     private Unbinder unbinder;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext=context;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置BaseDialog的样式
        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.BaseDialog);
       // mContentViewId = getLayoutId();  //获取布局Id
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (null==mView){
             //如果是指定类型注解类型则返回true
            if (getClass().isAnnotationPresent(ActivityFragmentInject.class)) {
                //通过反射获取 反射对象的方法等  返回该类中与参数类型匹配的公有注解对象
                ActivityFragmentInject annotation = getClass().getAnnotation(ActivityFragmentInject.class);
                //获得布局id
                mContentViewId = annotation.contentViewId();
            } else {
                //这里抛出了运行时异常
                throw new RuntimeException("Class must add annotations of ActivityFragmentInitParams.class");
            }
           mView =inflater.inflate(mContentViewId,container,false);
        }
       // convertView(BaseHolder,this);
        unbinder= ButterKnife.bind(this,mView);
        return mView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(mView,savedInstanceState,this);
    }

    @Override
    public void onStart() {
        super.onStart();
        initParams();//这个方法可以写成抽象方法,在具体的dialog里面进行具体的设置 当然这里写一个通用的也很好
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
    //初始化dialog
    private void initParams() {
        //因为dialogfragment 也是一种特殊的window
        //为什么在这里获取可以看一下fragment 的生命周期
        Window window = getDialog().getWindow();
        if (window!=null){
            WindowManager.LayoutParams params = window.getAttributes();
            params.dimAmount=mDimAmout;

            if (mShowBottomEnable){
               params.gravity= Gravity.BOTTOM;
            }

            //设置width
            if (mWidth==0){
                params.width=getScreenWidth(mContext)-2*dp2px(mContext,mMargin);
            }else {
                params.width=dp2px(mContext,mWidth);
            }

            //设置height
            if (mHeight==0){
                params.height=WindowManager.LayoutParams.WRAP_CONTENT;
            }else {
                params.height=dp2px(mContext,mHeight);
            }

            //设置动画
            if (mAnimStyle!=0){
                window.setWindowAnimations(mAnimStyle);
            }
            //设置窗口的属性
            window.setAttributes(params);
        }


        setCancelable(mOutCancel);

    }

    //操作dialog布局
    protected abstract void initView(View mView, Bundle savedInstanceState, BaseDialogFragment dialog);

    //float 区间 在0——1
    public void setDimAmout(@FloatRange(from = 0 ,to = 1 ) float mDimAmout) {
        this.mDimAmout = mDimAmout;
    }

    public void setShowBottomEnable(boolean mShowBottomEnable) {
        this.mShowBottomEnable = mShowBottomEnable;
    }

    public void setWidth(int mWidth) {
        this.mWidth = mWidth;
    }

    public void setHeight(int mHeight) {
        this.mHeight = mHeight;
    }

    public void setOutCancel(boolean mOutCancel) {
        this.mOutCancel = mOutCancel;
    }

    /**
     * 获取屏幕宽度
     *
     * @param context
     * @return
     */
    public static int getScreenWidth(Context context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        return displayMetrics.widthPixels;
    }

    public static int dp2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    protected void initToolbarMenu(Toolbar toolbar, TextView tvTitle, String title) {
        if (tvTitle != null && title != null) {
            tvTitle.setText(title);
        }
        if (toolbar != null) {
            toolbar.setTitle("");
            toolbar.setNavigationIcon(R.drawable.ic_left);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                }
            });
        }
    }

}

(3).rvDialog代码

import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;

import com.ycb.basedialog.R;
import com.ycb.basedialog.annotation.ActivityFragmentInject;

import java.util.ArrayList;

import butterknife.BindView;

/**
 * Created by asus on 2019/3/31.
 */
@ActivityFragmentInject(contentViewId = R.layout.rv_dialog)
public class RvDialog extends BaseDialogFragment {

    @BindView(R.id.iv_close)
    ImageView mIvClose;

    @BindView(R.id.recy)
    RecyclerView mRecy;
    private OnSelectListener<String> mOnSelectListener;
    private ArrayList<String> mList = new ArrayList<>();

    public static RvDialog newInstance(OnSelectListener<String> listener) {
        RvDialog dialog = new RvDialog();
        dialog.setOnSelectListener(listener);
        return dialog;
    }


    @Override
    protected void initView(View mView, Bundle savedInstanceState, BaseDialogFragment dialog) {
        initData();
        mIvClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        mRecy.setAdapter(new SingeLayoutAdapter<String>(getContext(), mList, R.layout.item_affair_sel) {
            @Override
            protected void onBinds(BaseHolder holder, final String s, int position) {
                holder.setText(R.id.tv_sel, s);
                holder.getItemView().setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mOnSelectListener != null) {
                            //实际上这个方法OnSelectListener<String> mOnSelectListener;
                            //是在这里执行的  传出了String值
                            mOnSelectListener.onSelected(s);
                        }
                        dismiss();
                    }
                });
            }
        });
        mRecy.setLayoutManager(new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false));
    }

    private void initData() {
        for (int i = 0; i < 3; i++) {
            mList.add("嘿哈" + i);
        }
    }

    public void setOnSelectListener(OnSelectListener<String> mOnSelectListener) {
        this.mOnSelectListener = mOnSelectListener;
    }
}

这里还涉及了BaseAdapter的写法     BaseAdapter封装

(4).MainActivity里面的点击方法


    public void showFriendClick(View view) {

        RvDialog.newInstance(new OnSelectListener<String>() {
            @Override
            public void onSelected(String select) {
                Toast.makeText(MainActivity.this,select,Toast.LENGTH_SHORT).show();
            }
        }).show(getSupportFragmentManager(),"tag");
    }

三、总结部分

代码下载

可以把BaseDialogFragment写的更加简洁一点,比如那个initParams可以写成抽象方法在具体的dialog里面写,毕竟使用的是RecyclerView,可以通过LayoutManageer设置各种样式,也可以在rvDialog里面有网络连接,显示接口返回的数据,做成查看聊天详情界面等都是可以的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值