前言
各位同学大家好 有段时间没有给各位更新文章了,最近在写新的项目 之前的手游sdk 都是用透明的activity 效果有缺陷,现在我改成用这个dialogfragment 来实现 , 废话不多说我们正式开始
效果图 :

为什么要使用dialogfragment:
之前开发手游sdk的时候 我这边都是使用透明的activity 虽然也能实现 但是遇到laya 白鹭这种弱语言引擎的时候 经常出现在打开sdk界面的时候. 或者在应用退到后台再切换回前台的时候经常出现有些黑屏的问题 ,所以最终我们选择使用弹窗来实现 为什么用dialogfragment 不是使用dialog 因为 dialogfragment 既有dialog的特性又有fragment的特性 我们可以用事务管理器 很好管理 dialogfragment 添加移除和替换等操作
具体实现
我们 sdk 接口的封装 : init login pay servicelogin updateuserinfo loginOut
生命周期接口 onDestroy onRestart onPause onResume onActivityResult onRequestPermissionsResult
typescript
package com.example.common;
import android.app.Activity;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.example.common.bean.RoleInfo;
import com.example.common.bean.ServiceInfo;
import com.example.common.dialog.OjjlgDialogManage;
import com.example.common.listener.InitListener;
import com.example.common.listener.LoginListener;
import com.example.common.listener.LoginoutListener;
import com.example.common.listener.ServiceLoginListener;
import com.example.common.listener.UpdateUserListener;
import com.example.common.utils.SharedPreferenceUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
public class NinefunSdk {
private static final String TAG = "NinefunSdk";
private Boolean initFlag=false;
private static NinefunSdk instance=null;
private NinefunSdk(){
}
public static NinefunSdk getInstance(){
if(instance==null){
synchronized (NinefunSdk.class){
if(instance==null){
instance=new NinefunSdk();
}
}
}
return instance;
}
public void init(Activity context, InitListener listener){
Map<String,String> map=new HashMap<>();
map.put("deviceid","2341414");
map.put("system_type","android");
map.put("version","1.1");
map.put("gid","35");
map.put("device","saff");
map.put("device_model","1214141");
map.put("platform_id","WEFWF");
map.put("device_brand","21E131");
OkHttpUtils.post().url(Config.INIT_URL).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
listener.initError();
}
@Override
public void onResponse(String s, int i) {
Log.e(TAG, "onResponse:s --- > "+s );
try {
JSONObject jsonObject=new JSONObject(s);
int code=jsonObject.optInt("code");
if(code==200){
initFlag=true;
listener.initSuccess();
}else{
listener.initError();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public void login(Activity context, LoginListener listener){
if(initFlag){
DataStore.getInstance().setListener(listener);
String token= (String) SharedPreferenceUtil.getPreference(context,"token","");
Log.e(TAG,"token --- > "+token);
if(!TextUtils.isEmpty(token)){
tokenSign(context,token,listener);
}else {
// OjjlgDialogManage.getInstance.clwuyShowSDKLoginDialog(context);
OjjlgDialogManage.getInstance().clwuyShowSDKLoginDialog(context);
}
}else{
Toast.makeText(context, "请先初始化", Toast.LENGTH_SHORT).show();
}
}
private void tokenSign(Activity contexr,String token ,LoginListener listener){
OkHttpUtils.get().url(Config.TOKEN_SIGN)
.addParams("token",token)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
listener.loginError();
}
@Override
public void onResponse(String s, int i) {
try {
JSONObject jsonObject=new JSONObject(s);
int code=jsonObject.optInt("code");
String msg=jsonObject.optString("msg");
if(code==200){
listener.loginSuccess(s);
Toast.makeText(contexr,msg,Toast.LENGTH_SHORT).show();
}else{
listener.loginError();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public void pay(Activity context, InitListener listener){
}
public void serviceLogin(ServiceInfo serviceInfo, ServiceLoginListener listener){
StringBuilder preSign = new StringBuilder();
preSign.append("sid=").append(serviceInfo.getSid());
preSign.append("&role_id=").append(serviceInfo.getRole_id());
preSign.append("&role_name=").append(serviceInfo.getRole_name());
preSign.append("||").append("0a649d6b-df9f-4583-bf7d-3fae84838519");
Map<String,String> map=new HashMap<>();
map.put("gid",serviceInfo.getGid());
map.put("sid",serviceInfo.getGid());
map.put("role_name",serviceInfo.getGid());
map.put("role_level",serviceInfo.getGid());
map.put("role_id",serviceInfo.getGid());
map.put("sign",preSign.toString());
OkHttpUtils.post().url(Config.SERVICE_LOGIN).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
listener.serviceloginError();
}
@Override
public void onResponse(String s, int i) {
try {
JSONObject jsonObject=new JSONObject(s);
int code=jsonObject.optInt("code");
if(code==200){
listener.serviceloginSuccess();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public void updateUserinfo(RoleInfo roleInfo, UpdateUserListener listener){
StringBuilder preSign = new StringBuilder();
preSign.append("sid=").append(roleInfo.getGid());
preSign.append("&role_id=").append(roleInfo.getRole_id());
preSign.append("&role_name=").append(roleInfo.getRole_name());
preSign.append("||").append("0a649d6b-df9f-4583-bf7d-3fae84838519");
Map<String,String> map=new HashMap<>();
map.put("gid",roleInfo.getGid());
map.put("sid",roleInfo.getGid());
map.put("role_name",roleInfo.getGid());
map.put("role_level",roleInfo.getGid());
map.put("role_id",roleInfo.getGid());
map.put("sign",preSign.toString());
OkHttpUtils.post().url(Config.UPDATE_USERINFO).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
listener.updateuserError();
}
@Override
public void onResponse(String s, int i) {
try {
JSONObject jsonObject=new JSONObject(s);
int code=jsonObject.optInt("code");
if(code==200){
listener.updateuserSuccess();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public void loginOut(Activity context, LoginoutListener listener){
SharedPreferenceUtil.removeKey(context,"token");
String gettoken= (String) SharedPreferenceUtil.getPreference(context,"token","");
if(TextUtils.isEmpty(gettoken)){
listener.loginoutSuccess();
}
}
/**
*
* @param context
* 生命周期方法
*/
public void onDestroy(Activity context){
}
public void onRestart(Activity context){
}
public void onPause(Activity context){
}
public void onResume(Activity context){
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
public void onRequestPermissionsResult(int requestCode,String[] permissions, int[] grantResults) {
}
}
登录界面实现
basedialogfragment
java
package com.example.common.dialog;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.Nullable;
import com.example.common.utils.ResourceUtil;
import java.lang.reflect.Method;
public abstract class OjjlgBaseDialogFragment extends DialogFragment {
public Activity mContext;
public Dialog mProgressdialog = null;
public abstract String clwuyGetLayoutId();
public abstract void clwuyInitView(View view);
public abstract void immpGetExtraParams();
public abstract void backdown();
public void backKeydown(){
getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
Log.d("KEYCODE_BACK","KEYCODE_BACK " + keyEvent.getKeyCode());
// google 正式推荐需要物理返回 键有用
if (i == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_UP) {
dismiss();
return true;
}
return false;
}
});
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
final Window window = getDialog().getWindow();
View view = inflater.inflate(ResourceUtil.getLayoutId(getActivity(), clwuyGetLayoutId()),
container);// 需要用android.R.id.content这个view
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));// 注意此处
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
// window.setGravity(Gravity.CENTER);
clwuySetFullScreen(getDialog());//dialog设置全屏
setCancelable(false);
backdown();
clwuyInitSoftInputListener();
immpGetExtraParams();
clwuyInitView(view);
return view;
}
@Override
public void onStart() {
super.onStart();
}
private void clwuySetFullScreen(final Dialog dialog){
dialog.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
dialog.getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
dialog.getWindow().getDecorView().setSystemUiVisibility(uiOptions);
}
});
}
private static String clwuyGetNavBarOverride() {
String sNavBarOverride = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Class c = Class.forName("android.os.SystemProperties");
Method m = c.getDeclaredMethod("get", String.class);
m.setAccessible(true);
sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
} catch (Throwable e) {
}
}
return sNavBarOverride;
}
private void clwuyInitSoftInputListener() {
getDialog().getWindow().getDecorView()
.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
InputMethodManager manager = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (getDialog().getCurrentFocus() != null
&& getDialog().getCurrentFocus().getWindowToken() != null) {
manager.hideSoftInputFromWindow(
getDialog().getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return false;
}
});
}
}
dialogfragment 事务管理OjjlgDialogManage
我们使用OjjlgDialogManage来管理我们的dialogfragment的添加和移除 还有替换
scss
package com.example.common.dialog;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import com.example.common.DataStore;
import com.example.common.LogUtils;
import java.util.HashMap;
import java.util.Map;
/***
* 创建人:xuqing
* 创建时间:2023年9月4日11:25:15
* 类说明:fragment 事务管理
*
*
*/
public class OjjlgDialogManage {
private final String TAG = getClass().toString();
Map<String,String> yxutlFragmentNameMap = new HashMap();
private static OjjlgDialogManage instacne=null;
public static OjjlgDialogManage getInstance(){
if(instacne==null){
synchronized (OjjlgDialogManage.class){
if(instacne==null){
instacne=new OjjlgDialogManage();
}
}
}
return instacne;
}
public synchronized void clwuyCancelDialog() {
try {
if(DataStore.getInstance().getContext()!=null){
DataStore.getInstance().getContext().runOnUiThread(new Runnable() {
@Override
public void run() {
//NbzgmLog.qecrnVUnControl("remove loading start ");
clwuyRemoveFragment(DataStore.getInstance().getContext(),"qecrnLoadingDialog");
}
});
}
}catch (Throwable e){
}
}
/**
* 判断dialog 是否存在
* @param context
* @param fragmentName
*/
public boolean clwuyIDialogHave(final Context context, final String fragmentName){
try{
FragmentManager fm = ((Activity) context).getFragmentManager();
Fragment fragment = fm.findFragmentByTag(fragmentName);
if(fragment!=null)
{
return true;
}else{
return false;
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
return false;
}
/**
* 移除Fragment
* @param context
* @param fragmentName 标签
*/
public void clwuyRemoveFragment(final Context context, final String fragmentName){
try {
if(DataStore.getInstance().getContext()!=null){
DataStore.getInstance().getContext().runOnUiThread(new Runnable() {
@Override
public void run() {
clwuyRemoveFragmentName(fragmentName);
FragmentManager fm = ((Activity) context).getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment fragment = fm.findFragmentByTag(fragmentName);
if(fragment!=null)
{
/*if("qecrnLoadingDialog".equals(fragmentName)){
NbzgmLog.qecrnVUnControl("remove loading ");
}*/
ft.remove(fragment);
ft.commit();
}
}
});
}
}catch (Throwable e){
}
}
/**
* 移除Fragment
* @param context
*/
public void clwuyRemoveAllFragment(Context context){
try {
LogUtils.e("removeAllFragment");
FragmentManager fm = ((Activity) context).getFragmentManager();
for (Map.Entry<String,String>entry:yxutlFragmentNameMap.entrySet() ){
String mapKey = entry.getKey();
Fragment fragment = fm.findFragmentByTag(mapKey);
if(fragment!=null)
{
FragmentTransaction ft = fm.beginTransaction();//这个必须放到里面,因为ft 每次只能commit 一次。所以需要放到里面
ft.remove(fragment);
ft.commit();
}
}
clwuyClearAllFragmentName();
}catch (Throwable e){
LogUtils.e("qecrnRemoveAllFragment"+e.toString());
}
}
/**
* 添加这个主要是为了方便移除所有的界面 ,没有使用 getFragments() 是因为现在android 0 api 26才能使用
* @param fragmentName
*/
private void clwuyPutFragmentName(String fragmentName){
yxutlFragmentNameMap.put(fragmentName,fragmentName);
}
private void clwuyRemoveFragmentName(String fragmentName){
if(yxutlFragmentNameMap.containsKey(fragmentName)){
yxutlFragmentNameMap.remove(fragmentName);
}
}
private void clwuyClearAllFragmentName(){
if(yxutlFragmentNameMap!=null&&yxutlFragmentNameMap.size()>0){
yxutlFragmentNameMap.clear();
}
}
/**
* 登录界面
*/
public void clwuyShowSDKLoginDialog(Activity activity){
try{
FragmentManager fm = ((Activity) activity).getFragmentManager();
Fragment fragment = fm.findFragmentByTag("clwuyShowSDKLoginDialog");
clwuyPutFragmentName("clwuyShowSDKLoginDialog");
FragmentTransaction ft = fm.beginTransaction();
if(fragment!=null)
{
ft.show(fragment);
}else{
OjjlgSdkLoginDialog dialog = new OjjlgSdkLoginDialog();
ft.add(dialog,"clwuyShowSDKLoginDialog");
ft.commitAllowingStateLoss();
}
}catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
}
登录界面的实现
我们可以根据需求来调用 backKeydown方法 如果需要屏蔽我们back 物理返回键就调用父类这个方法即可
ini
package com.example.common.dialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.common.Config;
import com.example.common.DataStore;
import com.example.common.R;
import com.example.common.bean.SelectPhone;
import com.example.common.listener.RemoveUserinfoListner;
import com.example.common.popupwindow.SpinerPopWindow;
import com.example.common.utils.KR;
import com.example.common.utils.ResourceUtil;
import com.example.common.utils.SharedPreferenceUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
/**
* 作者:xuqing
* 时间:
* 邮箱:[email protected]
* 说明: 登录界面
*/
public class OjjlgSdkLoginDialog extends OjjlgBaseDialogFragment implements View.OnClickListener {
private static final String TAG = "OjjlgSdkLoginDialog";
private EditText et_user_psd;
private TextView tv_login;
private EditText et_user_name;
private String account;
private String psd;
private Boolean flag=false;
private SpinerPopWindow<SelectPhone> mSpinerPopWindow;
private List<SelectPhone> data =null;
private List<SelectPhone> getcachedata = null;
private Boolean cache = false;
private View login_view;
private View iv_login_name_list;
@Override
public String clwuyGetLayoutId() {
return "activity_login";
}
@Override
public void clwuyInitView(View view) {
et_user_name= (EditText) view.findViewById(ResourceUtil.getId(mContext,"et_user_name"));
et_user_psd= (EditText) view.findViewById(ResourceUtil.getId(mContext,"et_user_psd"));
tv_login= (TextView) view.findViewById(ResourceUtil.getId(mContext,"tv_login"));
login_view=view.findViewById(ResourceUtil.getId(mContext,"login_view"));
iv_login_name_list=view.findViewById(ResourceUtil.getId(mContext,"iv_login_name_list"));
iv_login_name_list.setOnClickListener(this);
tv_login.setOnClickListener(this);
}
public void immpGetExtraParams() {
data = SharedPreferenceUtil.getSelectBean(mContext, "selectphone");
mSpinerPopWindow = new SpinerPopWindow<SelectPhone>(mContext,
data, itemClickListener, removeUserinfoListner);
mSpinerPopWindow.setOnDismissListener(dismissListener);
}
//删除用户缓存信息
private RemoveUserinfoListner removeUserinfoListner = new RemoveUserinfoListner() {
@Override
public void removeuserinfosuccess(int position, List<SelectPhone> data) {
if (data != null && data.size() > 0) {
data.remove(position);
SharedPreferenceUtil.putSelectBean(mContext, data, "selectphone");
cache = false;
List<SelectPhone> getdata = SharedPreferenceUtil.
getSelectBean(mContext, "selectphone");
if (getdata != null && getdata.size() > 0) {
SelectPhone selectPhone = getdata.get(0);
et_user_name.setText(selectPhone.getName());
et_user_psd.setText(selectPhone.getPassword());
} else {
et_user_name.setText(null);
et_user_psd.setText(null);
}
} else {
}
}
};
/**
* 监听popupwindow取消
*/
private PopupWindow.OnDismissListener dismissListener = new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
cache = false;
}
};
/**
* popupwindow显示的ListView的item点击事件
*/
private AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mSpinerPopWindow.dismiss();
cache = false;
SelectPhone selectPhone = data.get(position);
String getusername = selectPhone.getName();
String psw = selectPhone.getPassword();
et_user_name.setText(getusername);
et_user_psd.setText(psw);
}
};
@Override
public void backdown() {
super.backKeydown();
}
@Override
public void onClick(View v) {
if (v.getId() == ResourceUtil.getId(mContext, KR.id.tv_login)) {
sdkLogin();
}
//下拉输入框
if (v.getId() == ResourceUtil.getId(mContext, "iv_login_name_list")) {
if (cache) {
cache = false;
if (mSpinerPopWindow != null) {
mSpinerPopWindow.dismiss();
}
} else {
cache = true;
if (mSpinerPopWindow != null) {
mSpinerPopWindow.showAsDropDown(login_view);
}
}
}
}
private void sdkLogin() {
//用户名
account = et_user_name.getText().toString().trim();
//密码
psd = et_user_psd.getText().toString().trim();
if (TextUtils.isEmpty(account)) {
Toast.makeText(mContext, R.string.login_account_null, Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(psd)) {
Toast.makeText(mContext, R.string.login_psd_null, Toast.LENGTH_SHORT).show();
return;
}
if (account.length() < 6) {
Toast.makeText(mContext, R.string.login_account_less6, Toast.LENGTH_SHORT).show();
return;
}
if (psd.length() < 6) {
Toast.makeText(mContext, R.string.login_psd_less6, Toast.LENGTH_SHORT).show();
return;
}
loginServer();
}
//登陆接口
private void loginServer() {
Map<String, String> loginmap = new HashMap<>();
loginmap.put("username", account);
loginmap.put("password", psd);
OkHttpUtils.get().
url(Config.LOGIN_URL)
.params(loginmap)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String s, int id) {
Log.e(TAG, "onResponse: --- > "+s);
JSONObject jsonObject= null;
try {
jsonObject = new JSONObject(s);
int code=jsonObject.optInt("code");
String msg=jsonObject.optString("msg");
String token =jsonObject.optString("token");
if(code==200){
JSONObject datajson=jsonObject.optJSONObject("user");
SharedPreferenceUtil.savePreference(mContext,"token",token);
Log.e(TAG, "onResponse: token --- > "+token );
SelectPhone selectPhone = new SelectPhone();
selectPhone.setUserid(datajson.optString("id"));
selectPhone.setName(account);
selectPhone.setPassword(psd);
String user_id = datajson.optString("id");
//如果是token登录没有最新账号密码就不存到缓存里面 token登录没有账号密码
List<SelectPhone> spdata =new ArrayList<>();
List<SelectPhone> getdata = SharedPreferenceUtil.getSelectBean(mContext, "selectphone");
if (getdata != null && getdata.size() > 0) {
for (int i = 0; i < getdata.size(); i++) {
SelectPhone phone = getdata.get(i);
if (user_id.equals(phone.getUserid())) {
getdata.remove(i);
}
}
getdata.add(0,selectPhone);
SharedPreferenceUtil.putSelectBean(mContext, getdata, "selectphone");
} else {
spdata.add(selectPhone);
SharedPreferenceUtil.putSelectBean(mContext, spdata, "selectphone");
}
dismiss();
DataStore.getInstance().getListener().loginSuccess(s);
}else {
Toast.makeText(mContext,msg,Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
登录界面布局文件
ini
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="286dp"
android:layout_height="252dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
android:background="@drawable/bg_dialog_circle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:id="@+id/iv_login_back_rl"
android:layout_width="40dp"
android:layout_height="40dp">
<ImageView
android:id="@+id/iv_login_back"
android:layout_width="13dp"
android:layout_height="13dp"
android:layout_margin="13dp"
/>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="sdk登录"
android:textSize="25dp"
android:textColor="#119AD8"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/login_view_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:background="@drawable/bg_input_account"
android:orientation="horizontal">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="17dp"
android:src="@drawable/user_name" />
<EditText
android:id="@+id/et_user_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:background="@null"
android:digits="@string/account_type"
android:gravity="center_vertical"
android:hint="@string/login_input_account"
android:textColorHint="#a8a8a8"
android:textColor="#000000"
android:maxLength="20"
android:maxLines="1"
android:focusable="true"
android:focusableInTouchMode="true"
android:textSize="13sp" />
<ImageView
android:id="@+id/iv_login_name_list"
android:layout_width="26dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:scaleType="fitCenter"
android:src="@drawable/login_arrow_down"/>
</LinearLayout>
<View
android:id="@+id/login_view"
android:layout_width="match_parent"
android:layout_height="1dp"
>
</View>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:background="@drawable/bg_input_account"
android:orientation="horizontal">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="17dp"
android:src="@drawable/psd" />
<EditText
android:id="@+id/et_user_psd"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="7dp"
android:background="@null"
android:digits="@string/psd_type"
android:gravity="center_vertical"
android:hint="@string/login_input_password"
android:inputType="textPassword"
android:textColorHint="#a8a8a8"
android:textColor="#000000"
android:maxLength="20"
android:maxLines="1"
android:textSize="13sp" />
<FrameLayout
android:id="@+id/fr_select"
android:layout_width="40dp"
android:layout_height="match_parent"
android:visibility="gone"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/iv_vpsd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textOff=""
android:textOn="" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:layout_height="28dp"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_remember_psd"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:checked="true"
android:paddingLeft="5dp"
android:layout_alignParentRight="true"
android:text="@string/remember_psd"
android:textColor="#231816"
android:textSize="13sp" />
<TextView
android:id="@+id/tv_forgot_psd"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground"
android:gravity="center"
android:text="@string/find_back_psd"
android:textColor="#FE0E35"
android:textSize="13sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<TextView
android:id="@+id/ll_register"
android:layout_width="103dp"
android:layout_height="31dp"
android:background="@drawable/yellow_btn_middle_bg"
android:foreground="?android:attr/selectableItemBackground"
android:gravity="center"
android:text="@string/quick_register"
android:textColor="#7B4308"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_login"
android:layout_width="103dp"
android:layout_height="31dp"
android:layout_alignParentRight="true"
android:background="@drawable/blue_btn_bg"
android:foreground="?android:attr/selectableItemBackground"
android:gravity="center"
android:text="@string/login"
android:textColor="@color/white"
android:textSize="14sp" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
整个sdk 肯定不止这些功能我这边只是拿其中一个界面做演示使用,具体还是要看整个代码我这边会吧代码提交到码云 有兴趣的同学可以下载出来查阅
最后总结:
对比透明 activity 来说dialogfragment 是不会黑屏或者导致游戏暂停 但是很多回调我们就需要借助cp 也就是游戏里面的回调方法 所以我们要在对接文档备注清楚必须借的一些接口 生命周期接口 onDestroy onRestart onPause onResume onActivityResult onRequestPermissionsResult 可以保证我们功能的实现 。最后希望我都文章能帮助各位同学工作和学习 。如果觉得文章还不错希望能给我一个star 和转发