Android 纯代码布局编写手游sdk

前言 :

最近因为公司需求 上Google被查的很严, 所以就想着把代码重构 然后写布局也改成用代码写,所以就写了一个demo 然后我这边就想着 分享给各位同学

具体实现:

精简View的Base封装

-### 头部导航封装

标题文字

ini 复制代码
ls.gravity = Gravity.CENTER;
RelativeLayout titleLayout = new RelativeLayout(getContext());
//添加标题
mTitleTv = getTitleTv(getTitle());
titleLayout.addView(mTitleTv, ls);

左侧关闭

ini 复制代码
//关闭按钮
if(!TextUtils.isEmpty(backimagesrc)){

    backimage = new ImageView(getContext());
    //backimage.setPadding(_10dp, _5dp, _10dp, _5dp);
   //backimage.setBackground(DrawableUtils.createShape(1, C_COMFIRM));
    backimage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
            backimagesrc));
    RelativeLayout.LayoutParams backrl = new RelativeLayout.LayoutParams(_20dp, _20dp);
    backrl.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    backrl.leftMargin=_10dp;
    backrl.topMargin=_10dp;
    titleLayout.addView(backimage, backrl);
    backimage.setVisibility(View.VISIBLE);

    backimage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dismiss();
        }
    });

}

右侧关闭

ini 复制代码
// 右侧按钮

if(!TextUtils.isEmpty(closeimagesrc)){

    closeimage = new ImageView(getContext());
    closeimage.setPadding(_10dp, _5dp, _10dp, _5dp);
    closeimage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
            closeimagesrc));
    RelativeLayout.LayoutParams closerl = new RelativeLayout.LayoutParams(_20dp, _20dp);
    closerl.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    closerl.rightMargin = _10dp;
    closerl.topMargin = _10dp;
    titleLayout.addView(closeimage, closerl);
    closeimage.setVisibility(View.VISIBLE);

    closeimage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dismiss();

        }
    });
}
添加分割线和添加view到layout
ini 复制代码
ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
ls.gravity = Gravity.CENTER;
mParentView.addView(titleLayout, ls);

ls = new LinearLayout.LayoutParams(dp(25), dp(25));
ls.gravity = Gravity.CENTER;
ls.leftMargin = dp(5);
ls.topMargin = dp(5);

//添加分割线
mParentView.addView(addLine(getContext()), new LinearLayout.LayoutParams(MATCH_PARENT, dp(1)));//添加分割线

//添加内容
ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
ls.gravity = Gravity.CENTER;
ls.weight = 1;
mContentView = new LinearLayout(getContext());
mContentView.setOrientation(LinearLayout.VERTICAL);
mContentView.setGravity(Gravity.CENTER);
mContentView.setPadding(_10dp, 0, _10dp, _10dp);
setCanceledOnTouchOutside(false);
// setCancelable(false);
mParentView.addView(mContentView, ls);
setContentView(mParentView, new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));

完整SimpleBaseDialog代码

ini 复制代码
package com.lingyou.testfb.layout;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.InputType;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.*;
import com.lingyou.testfb.SimpleResultListener;
import com.lingyou.testfb.utils.DisplayUtils;
import com.lingyou.testfb.utils.DrawableUtils;
import com.lingyou.testfb.utils.ImmpResourceUtil;



/**
 * @author xuqing
 * @date :Created in 2021/4/25 0025 11:39
 * @description:精简View的Base封装
 */
public abstract class SimpleBaseDialog extends Dialog {
    protected final static int MATCH_PARENT = LinearLayout.LayoutParams.MATCH_PARENT;
    protected final static int WRAP_CONTENT = LinearLayout.LayoutParams.WRAP_CONTENT;

    protected final int _10dp = DisplayUtils.dip2Px(getContext(), 10);
    protected final int _5dp = DisplayUtils.dip2Px(getContext(), 5);
    protected final int _32dp = DisplayUtils.dip2Px(getContext(), 32);
    protected final int _20dp = DisplayUtils.dip2Px(getContext(), 20);

    public static final String C_COMFIRM = "#FF26ADF0";
    public static final String C_COMFIRM_P = "#DD26ADF0";
    public static final String C_CANCEL = "#FFCCCCCC";
    public static final String C_CANCEL_P = "#DDCCCCCC";

    public Context mContext;

    protected LinearLayout mParentView;
    protected LinearLayout mContentView;



    protected TextView mTitleTv;
    protected TextView closeBtn;
    protected ImageView backimage;
    protected ImageView closeimage;
    protected SimpleResultListener callbackListener;

    private  String backimagesrc;
    private  String closeimagesrc;



    public SimpleBaseDialog(Context context) {
        super(context);
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        this.mContext = context;
        initView();
    }

    public SimpleBaseDialog( Context context,String backimagesrc) {
        super(context);
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        this.mContext=context;
        this.backimagesrc=backimagesrc;
        initView();
    }



    public SimpleBaseDialog( Context context,String backimagesrc, String closeimagesrc) {
        super(context);
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        this.mContext=context;
        this.backimagesrc=backimagesrc;
        this.closeimagesrc=closeimagesrc;
        initView();
    }


    protected void initView() {

        mParentView = new LinearLayout(getContext());
        mParentView.setOrientation(LinearLayout.VERTICAL);
        mParentView.setPadding(0, 0, _5dp, _5dp);
        mParentView.setBackground(DrawableUtils.createShape("#ffffff"));
        LinearLayout.LayoutParams ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);



        ls.gravity = Gravity.CENTER;
        RelativeLayout titleLayout = new RelativeLayout(getContext());
        //添加标题
        mTitleTv = getTitleTv(getTitle());
        titleLayout.addView(mTitleTv, ls);

        //关闭按钮
        if(!TextUtils.isEmpty(backimagesrc)){

            backimage = new ImageView(getContext());
            //backimage.setPadding(_10dp, _5dp, _10dp, _5dp);
           //backimage.setBackground(DrawableUtils.createShape(1, C_COMFIRM));
            backimage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
                    backimagesrc));
            RelativeLayout.LayoutParams backrl = new RelativeLayout.LayoutParams(_20dp, _20dp);
            backrl.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            backrl.leftMargin=_10dp;
            backrl.topMargin=_10dp;
            titleLayout.addView(backimage, backrl);
            backimage.setVisibility(View.VISIBLE);

            backimage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                }
            });

        }

        // 右侧按钮

        if(!TextUtils.isEmpty(closeimagesrc)){

            closeimage = new ImageView(getContext());
            closeimage.setPadding(_10dp, _5dp, _10dp, _5dp);
            closeimage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
                    closeimagesrc));
            RelativeLayout.LayoutParams closerl = new RelativeLayout.LayoutParams(_20dp, _20dp);
            closerl.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            closerl.rightMargin = _10dp;
            closerl.topMargin = _10dp;
            titleLayout.addView(closeimage, closerl);
            closeimage.setVisibility(View.VISIBLE);

            closeimage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();

                }
            });
        }


        ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        mParentView.addView(titleLayout, ls);

        ls = new LinearLayout.LayoutParams(dp(25), dp(25));
        ls.gravity = Gravity.CENTER;
        ls.leftMargin = dp(5);
        ls.topMargin = dp(5);

        //添加分割线
        mParentView.addView(addLine(getContext()), new LinearLayout.LayoutParams(MATCH_PARENT, dp(1)));//添加分割线

        //添加内容
        ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        ls.weight = 1;
        mContentView = new LinearLayout(getContext());
        mContentView.setOrientation(LinearLayout.VERTICAL);
        mContentView.setGravity(Gravity.CENTER);
        mContentView.setPadding(_10dp, 0, _10dp, _10dp);
        setCanceledOnTouchOutside(false);
        // setCancelable(false);
        mParentView.addView(mContentView, ls);
        setContentView(mParentView, new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        initImpView();
    }


    public void changeTitle(String title) {
        if (mTitleTv != null) {
            mTitleTv.setText("" + title);
        }
    }

    protected void showCloseBtn(View.OnClickListener clickListener) {
        if (closeBtn != null) {
            closeBtn.setVisibility(View.VISIBLE);
            closeBtn.setOnClickListener(clickListener);
        }
    }

    protected TextView getTitleTv(String title) {
        TextView tv = new TextView(getContext());
        tv.setText("" + title);
        tv.setTextSize(16);
        //加粗
        TextPaint tp = tv.getPaint();
        tp.setFakeBoldText(true);
        tv.setMinHeight(dp(38));
        tv.setTextColor(0xff000000);
        tv.setGravity(Gravity.CENTER);
        return tv;
    }

    //改变父窗口的背景
    public void changeParentViewBackground(Drawable drawable) {
        if (mParentView != null) {
            mParentView.setBackground(drawable);
        }
    }

    //移除内容中的视图
    protected void removeContentView() {
        if (mContentView != null) {
            mContentView.removeAllViews();
        }
    }

    protected void addChild(ViewGroup parent, View child, int margintop) {
        LinearLayout.LayoutParams ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        ls.topMargin = DisplayUtils.dip2Px(getContext(), margintop);
        parent.addView(child, ls);
    }

    protected void addChild(ViewGroup parent, View child, ViewGroup.LayoutParams layoutParams) {
        if (layoutParams == null) {
            layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        }
        if (parent != null) {
            parent.addView(child, layoutParams);
        }
    }


    protected void addView(View view) {
        LinearLayout.LayoutParams ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        addView(view, ls);
    }


    protected void addView(View view, ViewGroup.LayoutParams layoutParams) {
        if (layoutParams == null) {
            layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        }
        if (mContentView != null) {
            mContentView.addView(view, layoutParams);


        }
    }

    protected void addView(View view, int margintopPx) {
        LinearLayout.LayoutParams ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        ls.topMargin = margintopPx;
        if (mContentView != null) {
            mContentView.addView(view, ls);

        }

    }


    protected void addView(View view, int margintopPx,View leftView) {
        LinearLayout.LayoutParams ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        ls.topMargin = margintopPx;
        if (mContentView != null) {
            mContentView.addView(leftView, ls);
            mContentView.addView(view, ls);
        }

    }


    protected void addView(View view, int margintopPx, View rightView,int marginPX) {
        LinearLayout.LayoutParams ls = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
        ls.gravity = Gravity.CENTER;
        ls.topMargin = margintopPx;
        if (mContentView != null) {
            mContentView.addView(view, ls);
        }
    }



    protected TextView addTextView() {
        TextView tv = new TextView(getContext());
        tv.setTextColor(0xff222222);
        tv.setTextSize(12);
        tv.setGravity(Gravity.CENTER_VERTICAL);
        return tv;
    }

    protected View addLine(Context context) {
        View line = new View(context);
        line.setBackgroundColor(0xffeaeaea);
        return line;
    }

    //添加取消按钮
    protected Button addCancelBtn(String text) {
        Button cancelBtn = new Button(getContext());
        //cancelBtn.setTextSize(10);
        cancelBtn.setTextColor(Color.GRAY);
        cancelBtn.setBackground(DrawableUtils.createStateDrawable(_5dp, C_COMFIRM, C_COMFIRM_P));
        cancelBtn.setText(text);
        cancelBtn.setPadding(_5dp, _5dp, _5dp, _5dp);
        return cancelBtn;
    }

    protected Button addConfirmBtn(String text) {
        Button confirmBtn = new Button(getContext());
        confirmBtn.setTextColor(Color.WHITE);
        confirmBtn.setBackground(DrawableUtils.createStateDrawable(_5dp, C_COMFIRM, C_COMFIRM_P));
        confirmBtn.setText(text);
        confirmBtn.setPadding(_5dp, _5dp, _5dp, _5dp);
        return confirmBtn;
    }


    protected EditText addEditText() {
        EditText et = new EditText(getContext());
        et.setSingleLine();
        et.setMinHeight(_32dp);
        et.setGravity(Gravity.CENTER_VERTICAL);
        et.setPadding(dp(5), 5, dp(2), 0);
        et.setTextSize(dp(4));
        et.setTextColor(Color.GRAY);
        et.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
        et.setBackground(DrawableUtils.createShape(1, 10, -1, "#000000", "#ffffff"));
        return et;
    }

    protected abstract String getTitle();


    protected abstract void initImpView();

    protected int dp(int _dp) {
        return DisplayUtils.dip2Px(getContext(), _dp);
    }

    protected int sp(int sp) {
        return DisplayUtils.sp2px(getContext(), sp);
    }


    @Override
    public void show() {
        super.show();
        DisplayMetrics dmDisplayMetrics = new DisplayMetrics(); //为获取屏幕宽、高
        getWindow().getWindowManager().getDefaultDisplay().getMetrics(dmDisplayMetrics);
        android.view.WindowManager.LayoutParams p = this.getWindow().getAttributes(); //获取对话框当前的参数值
        p.gravity = Gravity.CENTER;

ViewGroup.LayoutParams.WRAP_CONTENT);
        this.getWindow().setLayout(DisplayUtils.dip2Px(getContext(), 300), DisplayUtils.dip2Px(getContext(), 300));
    }


}

注册界面实现:

ini 复制代码
package com.lingyou.testfb.layout;

import android.content.Context;
import android.os.Bundle;
import android.text.InputType;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.lingyou.testfb.utils.DrawableUtils;
import com.lingyou.testfb.utils.ImmpResourceUtil;
import com.lingyou.testfb.utils.SPUtils;




/**
 * 作者:xuqing
 * 时间:2024年03月15日 15:55:27
 * 邮箱:1693891473@qq.com
 * 说明:注册界面
 */
public  class SimpleregisterDialog  extends SimpleBaseDialog{


    private EditText editAccount, editPwd,editnewpsw;
    protected LinearLayout editAccountiLlView,editPwdLlView,editnewpswLlView;
    private ImageView accountImage,editPwdImage,editnewpswImage;





    private  String backimagesrc;
    private  String closeimagesrc;
    private Context context;




    public SimpleregisterDialog(Context context) {
        super(context);
    }

    public SimpleregisterDialog(Context context, String backimagesrc) {
        super(context, backimagesrc);
    }

    public SimpleregisterDialog(Context context, String backimagesrc, String closeimagesrc) {
        super(context, backimagesrc, closeimagesrc);
    }

    @Override
    protected String getTitle() {
        return "快速注册";
    }



    @Override
    protected void initImpView() {

        editAccount = addEditText();
        editAccount.setHint("测试账号.");
        editAccount.setText((String) SPUtils.get(getContext(), "login_name", ""));
        LinearLayout.LayoutParams editAccountlayoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        editAccount.setLayoutParams(editAccountlayoutParams);
        editAccountlayoutParams.setMargins(dip2px(15),0,0,0);




        accountImage = new ImageView(getContext());
        accountImage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
                "ddsrwc_user_icon"));
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( dip2px(20),  dip2px(20));
        accountImage.setLayoutParams(layoutParams);

        //账号线性布局
        editAccountiLlView=new LinearLayout(getContext());
        editAccountiLlView.setOrientation(LinearLayout.HORIZONTAL);
        editAccountiLlView.setGravity(Gravity.CENTER);
        editAccountiLlView.setPadding(0, 0, _5dp, _5dp);
        editAccountiLlView.setBackground(DrawableUtils.createShape("#ffffff"));
        editAccountiLlView.addView(accountImage,layoutParams);
        editAccountiLlView.addView(editAccount,editAccountlayoutParams);
        addView(editAccountiLlView, _10dp);



        //输入密码
        editPwd = addEditText();
        LinearLayout.LayoutParams  editPwdlayoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        editPwd.setLayoutParams(editPwdlayoutParams);
        editAccountlayoutParams.setMargins(dip2px(15),0,0,0);
        editPwd.setGravity(Gravity.CENTER_VERTICAL);
        editPwd.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        editPwd.setHint("请输入密码.");


        editPwdImage = new ImageView(getContext());
        editPwdImage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
                "ddsrwc_psd_img"));
        LinearLayout.LayoutParams   editPwdImagelayoutParams = new LinearLayout.LayoutParams( dip2px(20),  dip2px(20));
        editPwdImage.setLayoutParams(editPwdImagelayoutParams);

        //账号线性布局
        editPwdLlView=new LinearLayout(getContext());
        editPwdLlView.setOrientation(LinearLayout.HORIZONTAL);
        editPwdLlView.setGravity(Gravity.CENTER);
        editPwdLlView.setPadding(0, 0, _5dp, _5dp);
        editPwdLlView.setBackground(DrawableUtils.createShape("#ffffff"));
        editPwdLlView.addView(editPwdImage,editPwdImagelayoutParams);
        editPwdLlView.addView(editPwd,editAccountlayoutParams);
        addView(editPwdLlView, _10dp);



        editnewpsw = addEditText();
        LinearLayout.LayoutParams  editnewpswlayoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        editnewpsw.setLayoutParams(editnewpswlayoutParams);
        editnewpswlayoutParams.setMargins(dip2px(15),0,0,0);
        editnewpsw.setGravity(Gravity.CENTER_VERTICAL);
        editnewpsw.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        editnewpsw.setHint("请输入密码.");


        editnewpswImage = new ImageView(getContext());
        editnewpswImage.setImageResource(ImmpResourceUtil.getDrawableId(mContext,
                "ddsrwc_psd_img"));
        LinearLayout.LayoutParams  eeditnewpswImagelayoutParams = new LinearLayout.LayoutParams( dip2px(20),  dip2px(20));
        editnewpswImage.setLayoutParams(eeditnewpswImagelayoutParams);

        //账号线性布局
        editnewpswLlView=new LinearLayout(getContext());
        editnewpswLlView.setOrientation(LinearLayout.HORIZONTAL);
        editnewpswLlView.setGravity(Gravity.CENTER);
        editnewpswLlView.setPadding(0, 0, _5dp, _5dp);
        editnewpswLlView.setBackground(DrawableUtils.createShape("#ffffff"));
        editnewpswLlView.addView(editnewpswImage,eeditnewpswImagelayoutParams);
        editnewpswLlView.addView(editnewpsw,editnewpswlayoutParams);
        addView(editnewpswLlView, _10dp);



        LinearLayout btnLayout = new LinearLayout(getContext());
        btnLayout.setOrientation(LinearLayout.HORIZONTAL);
        btnLayout.setGravity(Gravity.CENTER);
        addView(btnLayout, _10dp);


        //添加登陆
        LinearLayout.LayoutParams   lp = new LinearLayout.LayoutParams(0, _32dp);
        lp.weight = 1;
        lp.leftMargin = _5dp;
        Button loginBtn = addConfirmBtn("注册");
        btnLayout.addView(loginBtn, lp);

        loginBtn.setOnClickListener(v -> {
            String mUserAccount = editAccount.getText().toString().trim();
            String mPassword = editPwd.getText().toString().trim();
            if (TextUtils.isEmpty(mUserAccount)) {
                Toast.makeText(getContext(), "账号不能为空,请输入", Toast.LENGTH_SHORT).show();
                return;
            }

            SPUtils.put(getContext(), "注册", mUserAccount);
            if (callbackListener != null) {
                Bundle bundle = new Bundle();
                bundle.putString("username", mUserAccount);
                // bundle.putString("token", EncryptUtils.md5(mUserAccount));
                callbackListener.onSuccess(bundle);
                dismiss();
            }
        });

        setOnCancelListener(dialog -> {
            if (callbackListener != null) {
                callbackListener.onFail(-1, "登陆取消");
            }
        });
    }

    public int dip2px(float dpValue) {
        final float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);


    }

}

注册界面显示调用

ini 复制代码
SimpleregisterDialog simpleregisterDialog=new SimpleregisterDialog(context,"ddsrwc_back_icon");
simpleregisterDialog.show();

效果图

最后总结:

安卓的纯代码布局对比iOS纯代码确实要麻烦很多 但是也是可以写 弊端就是无法可视化预览 写起来效率低 好处就是缺少了xml 布局编译时候解析 然后再sdk打包的时候只需要打包java 代码即可 我们在坐马甲包的时候也可以做出更多差异化, 因为xml布局我们无法做过多的混淆和差异化。如果你觉得文章还不错麻烦给我三连 关注点赞和转发 谢谢

相关推荐
*才华有限公司*24 分钟前
安卓前后端连接教程
android
氦客1 小时前
Android Compose中的附带效应
android·compose·effect·jetpack·composable·附带效应·side effect
雨白1 小时前
Kotlin 协程的灵魂:结构化并发详解
android·kotlin
我命由我123451 小时前
Android 开发问题:getLeft、getRight、getTop、getBottom 方法返回的值都为 0
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
Modu_MrLiu1 小时前
Android实战进阶 - 用户闲置超时自动退出登录功能详解
android·超时保护·实战进阶·长时间未操作超时保护·闲置超时
Jeled2 小时前
Android 网络层最佳实践:Retrofit + OkHttp 封装与实战
android·okhttp·kotlin·android studio·retrofit
信田君95272 小时前
瑞莎星瑞(Radxa Orion O6) 基于 Android OS 使用 NPU的图片模糊查找APP 开发
android·人工智能·深度学习·神经网络
tangweiguo030519872 小时前
Kotlin 实现 Android 网络状态检测工具类
android·网络·kotlin
nvvas4 小时前
Android Studio JAVA开发按钮跳转功能
android·java·android studio
怪兽20144 小时前
Android多进程通信机制
android·面试