LZ-Say:在努力向前奔跑的途中,不要忘记让自己始终保持一个良好的状态,一颗初心,一颗永不言弃的心,一起加油`

前言

LZ虽说是搞Android的,但是对IOS的风格样式甚是酷爱,感觉简约大方,而今天,我们通过DialogFragment一起开启高仿之路~

本文目标

今天我们的目标简单可以概括为,通过DialogFragment高仿IOS弹框效果并对外公开,让大家可以通过一个地址调用,具体分为以下三部分:

  • 玩转DialogFragment;

  • 高仿IOS弹框效果;

  • 上传jcenter,方便有需要的人直接compile。

一、玩转DialogFragment

在此,不知道的大家可能会说,DialogFragment这是什么鬼?哈哈,主要LZ之前是真心没了解过这个东东,恕我孤陋寡闻~

下面为大家简单介绍下,主要还是LZ自己回顾下~ ^_^

DialogFragment简介

DialogFragment是在Android3.0(API level 11)中引入的,主要是为了替代AlertDialog(重点)。

DialogFragment优势

  • DialogFragment和Fragment生命周期基本一致,方便管理;

  • 完美兼容横竖屏切换,让你想怎么切,就怎么切~而我们之前使用的AlertDialog就out了~

话说上面说到我们之前玩转的AlertDialog对于横竖屏切换有点弱,有的伙伴说了,光说不练假把式,来个demo瞅瞅~

论:DialogFragment于AlertDialog横竖屏切换对比

首先编写一个AlertDialog例子,如下:

        // AlertDialogfindViewById(R.id.btn_alert_dialog).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {new AlertDialog.Builder(selfActivity).setTitle("测试标题").setMessage("Hello Word~!").setPositiveButton("哈喽", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {dialogInterface.dismiss();}}).show();}});

接着编写一个简单的DialogFragment例子,如下:

1. 定义LoadingDialog类

package cn.hlq.iosdialog.manager;import android.app.DialogFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;import cn.hlq.iosdialog.R;/*** create by heliquan at 2017年7月30日* Android 普通加载框*/
public class LoadingDialog extends DialogFragment {/*** 默认点击外面无效*/private boolean onTouchOutside = false;/*** 加载框提示信息 设置默认*/private String hintMsg = "正在加载,请稍后...";/*** 设置是否允许点击外面取消** @param onTouchOutside* @return*/public LoadingDialog setOnTouchOutside(boolean onTouchOutside) {this.onTouchOutside = onTouchOutside;return this;}/*** 设置加载框提示信息** @param hintMsg*/public LoadingDialog setHintMsg(String hintMsg) {if (!hintMsg.isEmpty()) {this.hintMsg = hintMsg;}return this;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 设置背景透明getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);// 去掉标题 死恶心死恶心的getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// set cancel on touch outsidegetDialog().setCanceledOnTouchOutside(onTouchOutside);View loadingView = inflater.inflate(R.layout.hlq_android_dialog_loading, container);TextView hintTextView = loadingView.findViewById(R.id.tv_loading_dialog_hint);hintTextView.setText(hintMsg);return loadingView;}}

代码编写完毕后,下面为大家附上对比图:

错误日志如下:

08-06 13:23:35.774 3403-3403/cn.hlq.iosdialog E/WindowManager: android.view.WindowLeaked: Activity cn.hlq.iosdialog.MainActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{eca8948 V.E...... R....... 0,0-1368,632} that was originally added hereat android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)at android.app.Dialog.show(Dialog.java:319)at android.app.AlertDialog$Builder.show(AlertDialog.java:1112)at cn.hlq.iosdialog.MainActivity$1.onClick(MainActivity.java:40)at android.view.View.performClick(View.java:5198)at android.view.View$PerformClick.run(View.java:21147)at android.os.Handler.handleCallback(Handler.java:739)at android.os.Handler.dispatchMessage(Handler.java:95)at android.os.Looper.loop(Looper.java:148)at android.app.ActivityThread.main(ActivityThread.java:5417)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

消失原因为,切换屏幕时,dialog没有被重新创建,从而造成窗口泄露。如果依然要使用AlertDialog而且不想横竖屏切换消失,LZ提供最简单方法去解决: 切换屏幕时候重新创建AlertDilog。(哈哈,不要打我~)

二、高仿IOS弹框效果

首先还是老规矩,看看效果,不然说不过去哈~

录制的效果不是很好,稍微有点模糊,Sorry~

我们将依次为大家介绍,瞧好吧您那~

仿IOS加载框 -> 传说中菊花转~ <-

首先要明确一个实现过程,具体如下:

  • 继承DialogFragment,重写onCreateView();

  • 编写布局文件,动画;

简单概括如上,下面依次附上源码,比较简单~

1. 定义IOSLoadingDialog菊花转类:

package cn.hlq.iosdialog.manager;import android.app.DialogFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;import cn.hlq.iosdialog.R;/*** Created by HLQ on 2017/7/31*/public class IOSLoadingDialog extends DialogFragment {/*** 默认点击外面无效*/private boolean onTouchOutside = false;/*** 加载框提示信息 设置默认*/private String hintMsg = "正在加载";/*** 设置是否允许点击外面取消** @param onTouchOutside* @return*/public IOSLoadingDialog setOnTouchOutside(boolean onTouchOutside) {this.onTouchOutside = onTouchOutside;return this;}/*** 设置加载框提示信息** @param hintMsg*/public IOSLoadingDialog setHintMsg(String hintMsg) {if (!hintMsg.isEmpty()) {this.hintMsg = hintMsg;}return this;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 设置背景透明getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);// 去掉标题 死恶心死恶心的getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// set cancel on touch outsidegetDialog().setCanceledOnTouchOutside(onTouchOutside);View loadingView = inflater.inflate(R.layout.hlq_ios_dialog_loading, container);TextView hintTextView = loadingView.findViewById(R.id.tv_ios_loading_dialog_hint);hintTextView.setText(hintMsg);return loadingView;}}

2. 定义布局文件:

<?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:background="@drawable/shape_ios_bg"android:gravity="center_vertical|center_horizontal"android:orientation="vertical"android:paddingBottom="15dp"android:paddingLeft="20dp"android:paddingRight="20dp"android:paddingTop="15dp"><ProgressBar
        android:id="@+id/progressBar"android:layout_width="40dp"android:layout_height="40dp"android:indeterminateBehavior="repeat"android:indeterminateDrawable="@drawable/anim_run_load"/><TextView
        android:id="@+id/tv_ios_loading_dialog_hint"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:textColor="#FFF"/></LinearLayout>

3. 来个动画`

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/ic_ios_loading"android:fromDegrees="0.0"android:pivotX="50.0%"android:pivotY="50.0%"android:toDegrees="-360.0"/>

4. 调用方式:

        // 高仿IOS加载框findViewById(R.id.btn_ios_loading_dialog).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {IOSLoadingDialog iosLoadingDialog = new IOSLoadingDialog().setOnTouchOutside(true);iosLoadingDialog.show(selfActivity.getFragmentManager(), "iosLoadingDialog");}});

回过头,我们来瞅瞅对外提供的方法:

  • 设置是否允许点击外面取消;

默认为false,可以通过setOnTouchOutside()设置是否允许点击外面取消。

  • 设置加载框提示信息;

默认为“正在加载”,可以通过setHintMsg()传入需要设置加载框提示信息。

仿IOS提示框

关于提示框,常用的一般有俩种类型,如下:

  • 提供用户俩个按钮,可确定或取消;

  • 只提供一个按钮,主要用于相关提示,提醒。

而实现流程,相对来说比较简单,今天主要是通过ViewStub去控制不同的显示隐藏,简单概括如下:

  • 继承DialogFragment,重写onCreateView;

  • 编写俩个按钮以及单个按钮布局;

  • 新增按下效果,对外开放相关方法内容。

1. 编写HintDialog类

package cn.hlq.iosdialog.manager;import android.app.DialogFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.Window;
import android.widget.TextView;import cn.hlq.iosdialog.R;/*** 提示框 Created by HLQ on 2017/6/15*/
public class HintDialog extends DialogFragment {private TextView tvTitle; // 标题private TextView tvContent; // 内容private TextView tvCancelTextView; // 取消private TextView tvConfirmTextView; // 确定private TextView tvSingleTextView; // 单个按钮/*** 确认回调*/private HintConfirmCallback confirmCallback;/*** 取消回调*/private HintCancelCallback cancelCallback;/*** 单选回调*/private HintSingleCallback singleCallback;private boolean isSingleButton = false; // 是否启用单个按钮/*** 默认点击外面无效*/private boolean onTouchOutside = false;/*** 标题*/private String title = "提示";/*** 内容*/private String content;private String confirm, cancel; // 确定 取消 可单独定制/*** 设置确定按钮内容** @param confirmMsg* @return*/public HintDialog setOnConfirmBtnText(String confirmMsg) {this.confirm = confirmMsg;return this;}/*** 设置取消按钮内容** @param cancelMsg* @return*/public HintDialog setOnCancelBtnText(String cancelMsg) {this.cancel = cancelMsg;return this;}/*** 设置是否启用单个按钮** @param isSingle* @return*/public HintDialog setIsSingleButton(boolean isSingle) {this.isSingleButton = isSingle;return this;}/*** 设置是否允许点击外面** @param onTouchOutside* @return*/public HintDialog setOnTouchOutside(boolean onTouchOutside) {this.onTouchOutside = onTouchOutside;return this;}/*** 设置标题** @param title* @return*/public HintDialog setTitle(String title) {if (!title.isEmpty()) {this.title = title;}return this;}/*** 设置内容** @param content* @return*/public HintDialog setContent(String content) {this.content = content;return this;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 设置背景透明getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);// 去掉标题 死恶心死恶心的getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// set cancel on touch outsidegetDialog().setCanceledOnTouchOutside(onTouchOutside);View hintView = inflater.inflate(R.layout.hlq_dialog_hint, null);initView(hintView);return hintView;}/*** 初始化View** @param hintView*/private void initView(View hintView) {tvTitle = hintView.findViewById(R.id.tv_hint_dialog_title);tvContent = hintView.findViewById(R.id.tv_hint_dialog_content);tvTitle.setText(title);tvContent.setText(content);if (isSingleButton) {ViewStub vsSingleButton = hintView.findViewById(R.id.vs_single_button);vsSingleButton.inflate();tvSingleTextView = hintView.findViewById(R.id.tv_single);tvSingleTextView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {singleCallback.onClick();}});} else {ViewStub vsDoubleButton = hintView.findViewById(R.id.vs_double_button);vsDoubleButton.inflate();tvCancelTextView = hintView.findViewById(R.id.btn_hint_dialog_cancle);tvConfirmTextView = hintView.findViewById(R.id.btn_hint_dialog_confirm);if (!"".equals(confirm) && confirm != null) {tvConfirmTextView.setText(confirm);}if (!"".equals(cancel) && cancel != null) {tvCancelTextView.setText(cancel);}tvConfirmTextView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {confirmCallback.onClick();}});tvCancelTextView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {cancelCallback.onClick();}});}}/*** 确定点击事件** @param confirmCallback* @return*/public HintDialog setOnConfirmClickListener(HintConfirmCallback confirmCallback) {this.confirmCallback = confirmCallback;return this;}/*** 取消点击事件** @param cancelCallback* @return*/public HintDialog setOnCancelClickListener(HintCancelCallback cancelCallback) {this.cancelCallback = cancelCallback;return this;}/*** 单个按钮点击事件** @param singleCallback* @return*/public HintDialog setOnSingleClickListener(HintSingleCallback singleCallback) {this.singleCallback = singleCallback;return this;}/*** 确认回调*/public interface HintConfirmCallback {void onClick();}/*** 取消回调*/public interface HintCancelCallback {void onClick();}/*** 单个按钮回调*/public interface HintSingleCallback {void onClick();}}

2. 编写布局文件
主布局如下:

<?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:background="@drawable/shape_base_bg"android:orientation="vertical"><TextView
        android:id="@+id/tv_hint_dialog_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:padding="10dp"android:text="标题"android:textColor="#333"android:textStyle="bold"/><View
        android:layout_width="match_parent"android:layout_height="1dp"android:background="#20000000"/><TextView
        android:id="@+id/tv_hint_dialog_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:padding="15dp"android:text="我是内容我是内容我是内容"android:textColor="#333"/><View
        android:layout_width="match_parent"android:layout_height="1dp"android:background="#20000000"/><ViewStub
        android:id="@+id/vs_single_button"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout="@layout/item_dialog_single_hint"/><ViewStub
        android:id="@+id/vs_double_button"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout="@layout/item_dialog_hint"/></LinearLayout>

单个按钮布局如下:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/tv_single"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/selector_dialog_hint"android:clickable="true"android:gravity="center"android:padding="10dp"android:text="确定"android:textColor="@android:color/holo_blue_light"/>

对应的按下样式文件如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- 选中时的颜色 --><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#20000000"/><corners android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"/></shape></item>
</selector>

俩个按钮布局如下:

<?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="horizontal"><TextView
        android:id="@+id/btn_hint_dialog_cancle"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/selector_dialog_hint_left"android:clickable="true"android:gravity="center"android:padding="10dp"android:text="取消"android:textColor="@android:color/holo_blue_dark"/><View
        android:layout_width="1dp"android:layout_height="match_parent"android:background="#20000000"/><TextView
        android:id="@+id/btn_hint_dialog_confirm"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/selector_dialog_hint_right"android:clickable="true"android:gravity="center"android:padding="10dp"android:text="确认"android:textColor="@android:color/holo_blue_dark"/></LinearLayout>

对应按下样式如下:
左侧按下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- 选中时的颜色 --><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#20000000"/><corners android:bottomLeftRadius="10dp"/></shape></item>
</selector>

右侧按下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- 选中时的颜色 --><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#20000000"/><corners android:bottomRightRadius="10dp"/></shape></item>
</selector>

3. 调用方式

        // 提示框findViewById(R.id.btn_ios_hint_dialog).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {hintDialog.setContent("确定要离开吗?");hintDialog.setOnConfirmClickListener(new HintDialog.HintConfirmCallback() {@Overridepublic void onClick() {hintDialog.dismiss();Toast.makeText(selfActivity, "点击确定", Toast.LENGTH_SHORT).show();}});hintDialog.setOnCancelClickListener(new HintDialog.HintCancelCallback() {@Overridepublic void onClick() {hintDialog.dismiss();Toast.makeText(selfActivity, "点击取消", Toast.LENGTH_SHORT).show();}});hintDialog.show(selfActivity.getFragmentManager(), "hintDialog");}});// 单个提示框findViewById(R.id.btn_ios_single_hint_dialog).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {singleHintDialog.setContent("请认真填写相关信息,谢谢合作~").setIsSingleButton(true);singleHintDialog.setOnSingleClickListener(new HintDialog.HintSingleCallback() {@Overridepublic void onClick() {singleHintDialog.dismiss();Toast.makeText(selfActivity, "点击确认~", Toast.LENGTH_SHORT).show();}});singleHintDialog.show(selfActivity.getFragmentManager(), "singleHintDialog");}});

对外提供方法如下:

  • setTitle() 设置标题 ,默认为“提示”;

  • setContent() 设置内容;

  • setIsSingleButton() 是否启用单个按钮模式;

  • setOnTouchOutside() 是否允许点击外面消失 默认不允许

仿IOS选择照片 选取相册

首先明确实现过程,如下:

  • 继承DialogFragment,重写onCreateView,并设置底部显示;

  • 设置布局文件以及按下效果;

  • 对外提供监听回调~

1. 编写PhotoDialog类

package cn.hlq.iosdialog.manager;import android.app.DialogFragment;
import android.os.Bundle;
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 cn.hlq.iosdialog.R;/*** 高仿IOS拍照 选择相册 Created by HLQ on 2017/8/1*/
public class PhotoDialog extends DialogFragment {private TextView tvTakeCamera; // 拍照private TextView tvChoosePhoto; // 选择相册private TextView tvCancel; // 取消private PhotoCameraCallback mPhotoCameraCallback;private ChoosePhotoCallback mChoosePhotoCallback;private PhoneCancelCallback mPhoneCancelCallback;/*** 默认点击外面无效*/private boolean onTouchOutside = false;/*** 设置是否允许点击外面取消** @param onTouchOutside* @return*/public PhotoDialog setOnTouchOutside(boolean onTouchOutside) {this.onTouchOutside = onTouchOutside;return this;}@Overridepublic void onResume() {super.onResume();WindowManager.LayoutParams mLayoutParams = getDialog().getWindow().getAttributes();mLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;mLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;getDialog().getWindow().setAttributes(mLayoutParams);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 设置底部显示getDialog().getWindow().setGravity(Gravity.BOTTOM);// 设置背景透明getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);// 去掉标题 死恶心死恶心的getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// set cancel on touch outsidegetDialog().setCanceledOnTouchOutside(onTouchOutside);View photoView = inflater.inflate(R.layout.hlq_ios_dialog_photo, null);initView(photoView);return photoView;}private void initView(View photoView) {tvTakeCamera = photoView.findViewById(R.id.tv_take_camera);tvChoosePhoto = photoView.findViewById(R.id.tv_choose_photo);tvCancel = photoView.findViewById(R.id.tv_cancel);tvTakeCamera.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mPhotoCameraCallback.onClick();}});tvChoosePhoto.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mChoosePhotoCallback.onClick();}});tvCancel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mPhoneCancelCallback.onClick();}});}/*** 拍照** @param photoCameraCallback* @return*/public PhotoDialog setOnCameraClickListener(PhotoCameraCallback photoCameraCallback) {this.mPhotoCameraCallback = photoCameraCallback;return this;}/*** 选择相册** @param choosePhotoCallback* @return*/public PhotoDialog setOnChoosePhotoClickListener(ChoosePhotoCallback choosePhotoCallback) {this.mChoosePhotoCallback = choosePhotoCallback;return this;}/*** 取消** @param phoneCancelCallback* @return*/public PhotoDialog setOnCancleClickListener(PhoneCancelCallback phoneCancelCallback) {this.mPhoneCancelCallback = phoneCancelCallback;return this;}/*** 拍照*/public interface PhotoCameraCallback {void onClick();}/*** 选取相册*/public interface ChoosePhotoCallback {void onClick();}/*** 取消*/public interface PhoneCancelCallback {void onClick();}}

2. 编写相应布局文件以及按下效果

主要布局文件如下:

<?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:gravity="center_vertical|center_horizontal"android:orientation="vertical"android:padding="15dp"><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/shape_base_bg"android:orientation="vertical"><TextView
            android:id="@+id/tv_take_camera"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/selector_photo_dialog_top"android:clickable="true"android:gravity="center"android:padding="12dp"android:text="拍照"android:textColor="@android:color/holo_blue_light"/><View
            android:layout_width="match_parent"android:layout_height="1dp"android:background="#FFDD"/><TextView
            android:id="@+id/tv_choose_photo"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/selector_dialog_hint"android:clickable="true"android:gravity="center"android:padding="12dp"android:text="选取相册"android:textColor="@android:color/holo_blue_light"/></LinearLayout><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:background="@drawable/shape_base_bg"><TextView
            android:id="@+id/tv_cancel"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/selector_photo_dialog_bottom"android:clickable="true"android:gravity="center"android:padding="12dp"android:text="取消"android:textColor="@android:color/holo_blue_light"/></LinearLayout>
</LinearLayout>

第一个item按下效果(只有左上和左上有弧度):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- 选中时的颜色 --><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#20000000"/><corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/></shape></item>
</selector>

第二个item按下效果(左下右下右弧度):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- 选中时的颜色 --><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#20000000"/><corners android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"/></shape></item>
</selector>

底部取消item按下效果:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- 选中时的颜色 --><item android:state_pressed="true"><shape android:shape="rectangle"><solid android:color="#20000000"/><corners android:radius="10dp"/></shape></item>
</selector>

调用方式如下:

        // 拍照 选取相册findViewById(R.id.btn_ios_camera_dialog).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {photoDialog.setOnCameraClickListener(new PhotoDialog.PhotoCameraCallback() {@Overridepublic void onClick() {photoDialog.dismiss();Toast.makeText(selfActivity, "点击拍照", Toast.LENGTH_SHORT).show();}});photoDialog.setOnChoosePhotoClickListener(new PhotoDialog.ChoosePhotoCallback() {@Overridepublic void onClick() {photoDialog.dismiss();Toast.makeText(selfActivity, "点击选取相册", Toast.LENGTH_SHORT).show();}});photoDialog.setOnCancleClickListener(new PhotoDialog.PhoneCancelCallback() {@Overridepublic void onClick() {photoDialog.dismiss();Toast.makeText(selfActivity, "点击取消", Toast.LENGTH_SHORT).show();}});photoDialog.show(selfActivity.getFragmentManager(), "");}});

三、JCenter简述、注册以及创建远程库

jcenter简述

jcenter,远程依赖库,选择它有如下几点原因:

  • 不仅仅兼容maven,而且支持更多不同形式远程仓库;

  • Android Studio中已经默认使用jcenter方式。

想要上传,首先要有个账号,下面为大家附上地址:

https://bintray.com/

账号注册以及创建我们第一个maven库

1. 点击进去后,点击Sign Up Here;

2. 点击进入注册界面,填写相关内容即可;

注册过程中,大家需要注意:

邮箱不支持qq 163啥的 可以使用谷歌 or outlook or foxmail;

3. 注册完成后,需进行邮箱验证,和我们平时使用流程一样,注册,验证,通过;

4. 登录成功后,查看API Key

输入密码点击Submit~

点击Show,把API Key复制下来。

5. 创建我们第一个库

回到登录首页,点击 Add New Repository,如下所示:

依次填写内容。

最后点击Create,会提示创建成功~

上传JCenter

方式一、通过gradle-bintray-plugin插件进行上传JCenter

Android Studio配置环境(属性)

1. 在工程下的build.gradle配置插件地址

    classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'

2. 在app下的build.grade添加如下内容

apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'//项目主页
def siteUrl = 'https://github.com/HLQ-Struggle/IOSDialog'    // project homepage
//项目的版本控制地址
def gitUrl = 'https://github.com/HLQ-Struggle/IOSDialog.git' // project git//发布到组织名称名字,必须填写
group = "com.hlq.struggle"
//发布到JCenter上的项目名字,必须填写
def libName = "ios-dialog"
// 版本号,下次更新是只需要更改版本号即可
version = "1.0"
/**  上面配置后上传至jcenter后的编译路径是这样的: compile 'com.hlq.struggle:ios-dialog:1.0'  **///生成源文件
task sourcesJar(type: Jar) {from android.sourceSets.main.java.srcDirsclassifier = 'sources'
}
//生成文档
task javadoc(type: Javadoc) {source = android.sourceSets.main.java.srcDirsclasspath += project.files(android.getBootClasspath().join(File.pathSeparator))// 如果你的项目里面有中文注释的话,必须将格式设置为UTF-8,不然会出现乱码options.encoding "UTF-8"options.charSet 'UTF-8'options.author trueoptions.version truefailOnError false
}//文档打包成jar
task javadocJar(type: Jar, dependsOn: javadoc) {classifier = 'javadoc'from javadoc.destinationDir
}//拷贝javadoc文件
task copyDoc(type: Copy) {from "${buildDir}/docs/"into "docs"
}//上传到jcenter所需要的源码文件
artifacts {archives javadocJararchives sourcesJar
}// 配置maven库,生成POM.xml文件
install {repositories.mavenInstaller {// This generates POM.xml with proper parameterspom {project {packaging 'aar'name 'This is a ios dialog for android' // 项目描述url siteUrllicenses {license { // 开源协议name 'This is a ios dialog for android'url 'https://github.com/HLQ-Struggle/IOSDialog'}}developers {developer {// 开发者个人信息id 'ios-dialog'name 'ios-dialog'email '925954424@qq.com'}}scm {connection gitUrldeveloperConnection gitUrlurl siteUrl}}}}
}//上传到jcenter
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {user = properties.getProperty("bintray.user")    //读取 local.properties 文件里面的 bintray.userkey = properties.getProperty("bintray.apikey")   //读取 local.properties 文件里面的 bintray.apikeyconfigurations = ['archives']pkg {repo = "maven"    // repo值必须要和创建Maven仓库的时候的名字一样name = libName    // 发布到JCenter上的项目名字,必须填写desc = 'This is a ios dialog for android'    //项目描述websiteUrl = siteUrlvcsUrl = gitUrllicenses = ["Apache-2.0"]publish = true}
}

3. 在local.properties中配置账号以及key(就是最早复制的key)

bintray.user=账号名
bintray.apikey=key

编译 生成jar包以及文档说明等。

依次执行下面命令,在Android Studio中点击Terminal即可

  • gradlew javadocJar

  • gradlew sourcesJar

  • gradlew install

  • gradlew bintrayUpload

上传进度完成后如下所示:

执行完毕后,maven下面就已经出现刚刚我们提交的资源文件,如下:

4. 以为这就好了?No,这仅仅完成了万里长征第一步

点击进去查看详情,点击“ADD to JCenter”,如下:

5. 输入描述信息,点击发送,提交JCenter工作人员审核即可。

发送之后,难倒我们就只能处于等待中了么?肿么可能。往下瞅瞅。

点击红框区域内复制标志,将复制内容粘贴到浏览器中,回车~biu~

在这里可以看到我们上传的一些资源文件,也可以理解为目前可以进行私人调用,But,还是等待审核通过一起666吧~

^_^ 静候审核消息吧~

6. 审核通过,一起来嗨皮~

不得不说人工作效率之高,没几个小时,就收到了message,如下:

Maven使用方式如下:

<dependency><groupId>com.hlq.struggle</groupId><artifactId>ios-dialog</artifactId><version>1.0</version><type>pom</type>
</dependency>

Gradle使用方式如下:

compile ‘com.hlq.struggle:ios-dialog:1.0’

方式二、通过bintray-release上传

建立一个Android Lib,按照如下操作流程进行操作即可,相对第一种方式,这种确实比较轻松。

1. 项目工程目录下添加依赖

classpath ‘com.novoda:bintray-release:0.3.4’

2. 要上传的lib的build添加publish,如下

publish {userOrg = 'hlq-struggle'//bintray.com用户名groupId = 'com.hlq-struggle'//jcenter上的路径artifactId = 'test'//项目名称publishVersion = '1.0.0'//版本号desc = 'This is test lib'//描述,不重要website = 'https://github.com/HLQ-Struggle'//网站,不重要
}

3. 运行如下命令

gradlew clean build bintrayUpload -PbintrayUser=hlq-struggle -PbintrayKey=jcenter key替换自己的 -PdryRun=false

回车之后,就会看到如下:

F:\HLQ_Study\BintrayReleaseStudy>gradlew clean build bintrayUpload -PbintrayUser=hlq-struggle -
Starting a Gradle Daemon, 1 busy and 2 incompatible and 1 stopped Daemons could not be reused,
use --status for detailsParallel execution with configuration on demand is an incubating feature.
Using the 'clean' task in combination with parallel execution may lead to unexpected runtime behavior.
Incremental java compilation is an incubating feature.
:app:clean
:hlqlibrary:clean
:clean
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2600Alpha1Library
:app:prepareComAndroidSupportAppcompatV72600Alpha1Library
:app:prepareComAndroidSupportConstraintConstraintLayout102Library
:app:prepareComAndroidSupportSupportCompat2600Alpha1Library
:app:prepareComAndroidSupportSupportCoreUi2600Alpha1Library
:app:prepareComAndroidSupportSupportCoreUtils2600Alpha1Library
:app:prepareComAndroidSupportSupportFragment2600Alpha1Library
:app:prepareComAndroidSupportSupportMediaCompat2600Alpha1Library
:app:prepareComAndroidSupportSupportV42600Alpha1Library
:app:prepareComAndroidSupportSupportVectorDrawable2600Alpha1Library
:app:prepareDebugDependencies
:app:compileDebugAidl
:app:compileDebugRenderscript
:app:generateDebugBuildConfig
:app:generateDebugResValues
:app:generateDebugResources
:app:mergeDebugResources
:hlqlibrary:preBuild UP-TO-DATE
:hlqlibrary:preDebugBuild UP-TO-DATE
:hlqlibrary:checkDebugManifest
:hlqlibrary:preDebugAndroidTestBuild UP-TO-DATE
:hlqlibrary:preDebugUnitTestBuild UP-TO-DATE
:hlqlibrary:preReleaseBuild UP-TO-DATE
:hlqlibrary:preReleaseUnitTestBuild UP-TO-DATE
:hlqlibrary:prepareComAndroidSupportAnimatedVectorDrawable2600Alpha1Library
:hlqlibrary:prepareComAndroidSupportAppcompatV72600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportCompat2600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportCoreUi2600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportCoreUtils2600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportFragment2600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportMediaCompat2600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportV42600Alpha1Library
:hlqlibrary:prepareComAndroidSupportSupportVectorDrawable2600Alpha1Library
:hlqlibrary:prepareDebugDependencies
:hlqlibrary:compileDebugAidl
:hlqlibrary:compileDebugNdk UP-TO-DATE
:hlqlibrary:compileLint
:hlqlibrary:copyDebugLint UP-TO-DATE
:hlqlibrary:compileDebugRenderscript
:hlqlibrary:generateDebugBuildConfig
:hlqlibrary:generateDebugResValues
:hlqlibrary:generateDebugResources
:hlqlibrary:mergeDebugResources
:app:processDebugManifest
:app:processDebugResources
:app:generateDebugSources
:app:incrementalDebugJavaCompilationSafeguard
:app:javaPreCompileDebug
:app:compileDebugJavaWithJavac
:app:compileDebugJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:hlqlibrary:processDebugManifest
:hlqlibrary:processDebugResources
:hlqlibrary:generateDebugSources
:hlqlibrary:incrementalDebugJavaCompilationSafeguard
:hlqlibrary:javaPreCompileDebug
:hlqlibrary:compileDebugJavaWithJavac
:hlqlibrary:compileDebugJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:mergeDebugShaders
:app:compileDebugShaders
:app:generateDebugAssets
:app:mergeDebugAssets
:hlqlibrary:extractDebugAnnotations
:app:transformClassesWithDexForDebug
:app:mergeDebugJniLibFolders
:app:transformNativeLibsWithMergeJniLibsForDebug
:hlqlibrary:mergeDebugShaders
:hlqlibrary:compileDebugShaders
:hlqlibrary:generateDebugAssets
:hlqlibrary:mergeDebugAssets
:hlqlibrary:mergeDebugProguardFiles
:hlqlibrary:packageDebugRenderscript UP-TO-DATE
:hlqlibrary:packageDebugResources
:app:transformNativeLibsWithStripDebugSymbolForDebug
:app:processDebugJavaRes UP-TO-DATE
:app:transformResourcesWithMergeJavaResForDebug
:hlqlibrary:processDebugJavaRes UP-TO-DATE
:hlqlibrary:transformResourcesWithMergeJavaResForDebug
:hlqlibrary:transformClassesAndResourcesWithSyncLibJarsForDebug
:app:validateSigningDebug
:app:packageDebug
:hlqlibrary:mergeDebugJniLibFolders
:hlqlibrary:transformNativeLibsWithMergeJniLibsForDebug
:hlqlibrary:transformNativeLibsWithStripDebugSymbolForDebug
:hlqlibrary:transformNativeLibsWithSyncJniLibsForDebug
:hlqlibrary:bundleDebug
:hlqlibrary:compileDebugSources
:hlqlibrary:assembleDebug
:hlqlibrary:checkReleaseManifest
:hlqlibrary:prepareReleaseDependencies
:hlqlibrary:compileReleaseAidl
:hlqlibrary:compileReleaseNdk UP-TO-DATE
:hlqlibrary:copyReleaseLint UP-TO-DATE
:hlqlibrary:compileReleaseRenderscript
:hlqlibrary:generateReleaseBuildConfig
:hlqlibrary:generateReleaseResValues
:hlqlibrary:generateReleaseResources
:hlqlibrary:mergeReleaseResources
:app:assembleDebug
:app:checkReleaseManifest
:app:prepareReleaseDependencies
:app:compileReleaseAidl
:app:compileReleaseRenderscript
:app:generateReleaseBuildConfig
:app:generateReleaseResValues
:app:generateReleaseResources
:app:mergeReleaseResources
:hlqlibrary:processReleaseManifest
:hlqlibrary:processReleaseResources
:hlqlibrary:generateReleaseSources
:hlqlibrary:incrementalReleaseJavaCompilationSafeguard
:hlqlibrary:javaPreCompileRelease
:hlqlibrary:compileReleaseJavaWithJavac
:hlqlibrary:compileReleaseJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:hlqlibrary:extractReleaseAnnotations
:hlqlibrary:mergeReleaseShaders
:hlqlibrary:compileReleaseShaders
:hlqlibrary:generateReleaseAssets
:hlqlibrary:mergeReleaseAssets
:hlqlibrary:mergeReleaseProguardFiles
:hlqlibrary:packageReleaseRenderscript UP-TO-DATE
:hlqlibrary:packageReleaseResources
:hlqlibrary:processReleaseJavaRes UP-TO-DATE
:hlqlibrary:transformResourcesWithMergeJavaResForRelease
:hlqlibrary:transformClassesAndResourcesWithSyncLibJarsForRelease
:hlqlibrary:mergeReleaseJniLibFolders
:hlqlibrary:transformNativeLibsWithMergeJniLibsForRelease
:hlqlibrary:transformNativeLibsWithStripDebugSymbolForRelease
:hlqlibrary:transformNativeLibsWithSyncJniLibsForRelease
:hlqlibrary:bundleRelease
:hlqlibrary:compileReleaseSources
:hlqlibrary:assembleRelease
:hlqlibrary:assemble
:hlqlibrary:lint
Ran lint on variant debug: 1 issues found
Ran lint on variant release: 1 issues found
Wrote HTML report to file:///F:/HLQ_Study/BintrayReleaseStudy/hlqlibrary/build/reports/lint-results.html
Wrote XML report to file:///F:/HLQ_Study/BintrayReleaseStudy/hlqlibrary/build/reports/lint-results.xml
:hlqlibrary:incrementalDebugUnitTestJavaCompilationSafeguard UP-TO-DATE
:hlqlibrary:javaPreCompileDebugUnitTest
:hlqlibrary:prepareDebugUnitTestDependencies
:hlqlibrary:compileDebugUnitTestJavaWithJavac
:hlqlibrary:processDebugUnitTestJavaRes UP-TO-DATE
:hlqlibrary:compileDebugUnitTestSources
:hlqlibrary:mockableAndroidJar
:hlqlibrary:assembleDebugUnitTest
:hlqlibrary:testDebugUnitTest
:hlqlibrary:incrementalReleaseUnitTestJavaCompilationSafeguard UP-TO-DATE
:hlqlibrary:javaPreCompileReleaseUnitTest
:hlqlibrary:prepareReleaseUnitTestDependencies
:hlqlibrary:compileReleaseUnitTestJavaWithJavac
:hlqlibrary:processReleaseUnitTestJavaRes UP-TO-DATE
:hlqlibrary:compileReleaseUnitTestSources
:hlqlibrary:assembleReleaseUnitTest
:hlqlibrary:testReleaseUnitTest
:hlqlibrary:test
:hlqlibrary:check
:hlqlibrary:build
:hlqlibrary:bintrayUpload
:app:processReleaseManifest
:app:processReleaseResources
:app:generateReleaseSources
:app:incrementalReleaseJavaCompilationSafeguard
:app:javaPreCompileRelease
:app:compileReleaseJavaWithJavac
:app:compileReleaseJavaWithJavac - is not incremental (e.g. outputs have changed, no previous execution, etc.).
:app:compileReleaseNdk UP-TO-DATE
:app:compileReleaseSources
:app:lintVitalRelease
:app:mergeReleaseShaders
:app:compileReleaseShaders
:app:generateReleaseAssets
:app:mergeReleaseAssets
:app:transformClassesWithDexForRelease
:app:mergeReleaseJniLibFolders
:app:transformNativeLibsWithMergeJniLibsForRelease
:app:transformNativeLibsWithStripDebugSymbolForRelease
:app:processReleaseJavaRes UP-TO-DATE
:app:transformResourcesWithMergeJavaResForRelease
:app:packageRelease
:app:assembleRelease
:app:assemble
:app:lint
Skipping upload for missing file 'F:\HLQ_Study\BintrayReleaseStudy\hlqlibrary\build\libs\hlqlibrary-sources.jar'.
Skipping upload for missing file 'F:\HLQ_Study\BintrayReleaseStudy\hlqlibrary\build\libs\hlqlibrary-javadoc.jar'.
Ran lint on variant release: 3 issues found
Ran lint on variant debug: 3 issues found
Wrote HTML report to file:///F:/HLQ_Study/BintrayReleaseStudy/app/build/reports/lint-results.html
Wrote XML report to file:///F:/HLQ_Study/BintrayReleaseStudy/app/build/reports/lint-results.xml
:app:incrementalDebugUnitTestJavaCompilationSafeguard UP-TO-DATE
:app:javaPreCompileDebugUnitTest
:app:preDebugUnitTestBuild UP-TO-DATE
:app:prepareDebugUnitTestDependencies
:app:compileDebugUnitTestJavaWithJavac
:app:processDebugUnitTestJavaRes UP-TO-DATE
:app:compileDebugUnitTestSources
:app:mockableAndroidJar
:app:assembleDebugUnitTest
:app:testDebugUnitTest
Skipping upload for missing file 'F:\HLQ_Study\BintrayReleaseStudy\hlqlibrary\build\publications\maven\pom-default.xml'.
:app:incrementalReleaseUnitTestJavaCompilationSafeguard UP-TO-DATE
:app:javaPreCompileReleaseUnitTest
:app:preReleaseUnitTestBuild UP-TO-DATE
:app:prepareReleaseUnitTestDependencies
:app:compileReleaseUnitTestJavaWithJavac
:app:processReleaseUnitTestJavaRes UP-TO-DATE
:app:compileReleaseUnitTestSources
:app:assembleReleaseUnitTest
:app:testReleaseUnitTest
:app:test
:app:check
:app:buildBUILD SUCCESSFULTotal time: 5 mins 37.242 secs

重点是BUILD SUCCESSFUL

接下来,我们去jcenter上面刷新一下,如下:

下面的步骤和第一步的都一样,这里不做说明。

GitHub查看地址

https://github.com/HLQ-Struggle/IOSDialog

参考资源

参考地址如下,万分感谢~

  1. http://www.cnblogs.com/qianxudetianxia/p/4322331.html;
  2. http://blog.csdn.net/lmj623565791/article/details/51148825;

最新文章

  1. mysql 查看blob字段大小_MYSQL BLOB 字段大小以及个数的限制测试。
  2. Spring装配Bean---使用xml配置
  3. python支付程序源码_python项目中实现支付宝网页支付
  4. C++利用二次探查实现存储机制hash table的算法(附完整源码)
  5. 操作系统之内存管理:3、基本分页存储管理
  6. python bokeh_使用Bokeh将交互性添加到您的Python图中
  7. UI设计实用素材|线框套件 WRFRM
  8. 我眼中的Web2.0
  9. oracle excute call,oracle – EXECUTE识别存储过程,CALL不识别
  10. PHP开发者最好的学习资源收集
  11. PyQt5系列(三)Python3.x AttributeError: module 'string' has no attribute 'maketrans'错误解决
  12. 一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用
  13. 超市商品管理系统php,超市商品管理系统(含附源代码)超市商品管理系统(含附源代码).doc...
  14. delphi完美经典--第十八章
  15. 常见字读音(粤语)---(3)
  16. 访问ftp服务器不显示文件夹权限问题,访问ftp服务器显示无权限问题
  17. python 二项分布_Python-二项式分布
  18. postgis+geoserver最短路径
  19. 020 Rust死灵书之展开
  20. Kinect for Windows SDK v2.0 开发笔记 (五)骨骼帧与笑面男

热门文章

  1. 【CSS】固定区域竖向滚动
  2. Linux下wait_for_completion引起的开机定屏
  3. js/javascript获取时间戳的5种方法
  4. 帝国cms如何域名html的专题,帝国cms整站更换新老域名详细操作方法
  5. jnz和djnz_djnz(单片机djnz指令的功能)
  6. Large-Scale Global Optimization Using Cooperative Coevolution with Variable Interaction Learning
  7. 人工智能——问题求解
  8. 联想小新触摸板驱动_如何下载并安装触控板驱动
  9. PAD智龙迷城(puzzle and dragon)辅助转珠算法思路和python实现
  10. 简单实用的pandas技巧:如何将内存占用降低90%