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例子,如下:
// AlertDialog
findViewById(R.id.btn_alert_dialog).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(selfActivity).setTitle("测试标题").setMessage("Hello Word~!").setPositiveButton("哈喽", new DialogInterface.OnClickListener() {
@Override
public 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;
}
@Override
public 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 outside
getDialog().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 here
at 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;
}
@Override
public 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 outside
getDialog().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() {
@Override
public 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;
}
@Override
public 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 outside
getDialog().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() {
@Override
public 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() {
@Override
public void onClick(View v) {
confirmCallback.onClick();
}
});
tvCancelTextView.setOnClickListener(new View.OnClickListener() {
@Override
public 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() {
@Override
public void onClick(View view) {
hintDialog.setContent("确定要离开吗?");
hintDialog.setOnConfirmClickListener(new HintDialog.HintConfirmCallback() {
@Override
public void onClick() {
hintDialog.dismiss();
Toast.makeText(selfActivity, "点击确定", Toast.LENGTH_SHORT).show();
}
});
hintDialog.setOnCancelClickListener(new HintDialog.HintCancelCallback() {
@Override
public 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() {
@Override
public void onClick(View view) {
singleHintDialog.setContent("请认真填写相关信息,谢谢合作~").setIsSingleButton(true);
singleHintDialog.setOnSingleClickListener(new HintDialog.HintSingleCallback() {
@Override
public 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;
}
@Override
public 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);
}
@Override
public 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 outside
getDialog().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() {
@Override
public void onClick(View view) {
mPhotoCameraCallback.onClick();
}
});
tvChoosePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mChoosePhotoCallback.onClick();
}
});
tvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public 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() {
@Override
public void onClick(View view) {
photoDialog.setOnCameraClickListener(new PhotoDialog.PhotoCameraCallback() {
@Override
public void onClick() {
photoDialog.dismiss();
Toast.makeText(selfActivity, "点击拍照", Toast.LENGTH_SHORT).show();
}
});
photoDialog.setOnChoosePhotoClickListener(new PhotoDialog.ChoosePhotoCallback() {
@Override
public void onClick() {
photoDialog.dismiss();
Toast.makeText(selfActivity, "点击选取相册", Toast.LENGTH_SHORT).show();
}
});
photoDialog.setOnCancleClickListener(new PhotoDialog.PhoneCancelCallback() {
@Override
public void onClick() {
photoDialog.dismiss();
Toast.makeText(selfActivity, "点击取消", Toast.LENGTH_SHORT).show();
}
});
photoDialog.show(selfActivity.getFragmentManager(), "");
}
});
三、JCenter简述、注册以及创建远程库
jcenter简述
jcenter,远程依赖库,选择它有如下几点原因:
- 不仅仅兼容maven,而且支持更多不同形式远程仓库;
- Android Studio中已经默认使用jcenter方式。
想要上传,首先要有个账号,下面为大家附上地址:
账号注册以及创建我们第一个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.srcDirs
classifier = 'sources'
}
//生成文档
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
// 如果你的项目里面有中文注释的话,必须将格式设置为UTF-8,不然会出现乱码
options.encoding "UTF-8"
options.charSet 'UTF-8'
options.author true
options.version true
failOnError 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 javadocJar
archives sourcesJar
}
// 配置maven库,生成POM.xml文件
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom {
project {
packaging 'aar'
name 'This is a ios dialog for android' // 项目描述
url siteUrl
licenses {
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 '[email protected]'
}
}
scm {
connection gitUrl
developerConnection gitUrl
url siteUrl
}
}
}
}
}
//上传到jcenter
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
user = properties.getProperty("bintray.user") //读取 local.properties 文件里面的 bintray.user
key = properties.getProperty("bintray.apikey") //读取 local.properties 文件里面的 bintray.apikey
configurations = ['archives']
pkg {
repo = "maven" // repo值必须要和创建Maven仓库的时候的名字一样
name = libName // 发布到JCenter上的项目名字,必须填写
desc = 'This is a ios dialog for android' //项目描述
websiteUrl = siteUrl
vcsUrl = gitUrl
licenses = ["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 details
Parallel 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:build
BUILD SUCCESSFUL
Total time: 5 mins 37.242 secs
重点是BUILD SUCCESSFUL。
接下来,我们去jcenter上面刷新一下,如下:
下面的步骤和第一步的都一样,这里不做说明。
GitHub查看地址
标签:layout,Study,IOS,弹框,public,hlqlibrary,id,android,app From: https://blog.51cto.com/u_13346181/5842256