Android开发艺术探索第六章——Android的Drawable

简介: Android开发艺术探索第六章——Android的Drawable这本书的涉及面真的很抓重点,这章说的是Drawable,Drawable表示的是一种可以在Canvas上进行绘制的抽象概念,Drawable可不光是指图片,其实他的种类也特别繁多,在实际开发当中,他使用简...

Android开发艺术探索第六章——Android的Drawable


这本书的涉及面真的很抓重点,这章说的是Drawable,Drawable表示的是一种可以在Canvas上进行绘制的抽象概念,Drawable可不光是指图片,其实他的种类也特别繁多,在实际开发当中,他使用简单,而且对大小,效率都有不错的效果,所以是我们不可或缺的一个知识点,我们接下来就来聊聊Drawable给我们带来了哪些好处!

一.Drawable的简介

在Android中,Drawable可不是单单的图片那么简单,他说直观点可以理解为一种图片的抽象概念,通过颜色也可以定义出各式各样的图片,在实际开发中,Drawable常常被作为一个View的背景,一般分XML和图片两种,当然,我们也可以用图片来实现,不过这种方式就比较复杂了,Drawable作为一个抽象类,他衍生出了很多的子类,我们可以看下他的结构图

这里写图片描述

Drawable的内部宽高参数很重要,通过getIntrinsicWidth和getIntrinsicHeight这两个方法可以获取到他们,但是比并不是所有的Drawable都有内部宽高,比如一张图片所形成的Drawable,他就有,但是如果你是颜色所形成的的,那就自然是没有的,,而且要注意的是,内部宽高不等于他的大小,因为当View是北京,会被拉伸至View的等同大小

二.Drawable的分类

Drawable的种类是比较多的,比如我们之前常用的ShapeDrawable,BitmapDrawable,LayerDrawable,StateListDrawable等,注意的是,StateListDrawable是DrawableContainer的子类,接下来,我们继续看下这些种类繁多的Drawable到底有什么神奇的地方

1.BitmapDrawable

BitmapDrawable是比较简单的一张图片的Drawable,我们在实际开发中,可以直接设置为View的背景,也可以通过XML的形式来描述BitmapDrawable展示更多的效果,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="center"
    android:mipMap="true"
    android:src="@color/colorPrimaryDark"
    android:tileMode="clamp">

</bitmap>

下面我们来看下他们的含义都是什么

  • android:src

这个是资源,可以是图片也可以是颜色

  • android:antialias

是否开启图片抗锯齿,开启后图片会变得平滑一点,同时也会在一定程度上降低清晰度,不过这个降低我们完全可以无视,所以这个可以开启

  • android:dither

是否开启抖动效果,当图片的像素配置和手机不一致的时候,开启这个选项可以让高质量的图片在低分辨率的屏幕上保持比较好的显示效果,比如图片的色彩模式ARGB8888,但是设备只支持RGB555,这个时候开启抖动模式可以让图片不会过于失真,在Android中创建的Bitmap一般会使用ARGB8888这个模式,即ARGB四个通道各占8位,在这个色彩下,一个像素所占为4个字节,一个像素的位数综合越高,图片越逼真,抖动也应该开启

  • android:filter

是否开启过滤效果,当图片尺寸被拉伸或者压缩时,开启过滤效果会保持比较好的显示效果,所以这个也可开启

  • android:gravity

这个就不用说,位置方向,上下左右,可以用“|”符号来实现左上,右下等效果,可以具体看下他的属性,如图

这里写图片描述

  • android:mipMap

这是一种图片相关的处理技术,也叫纹理映射,比较抽象,默认为false,不常用

  • android:tileMode

平铺模式,这个选项有几个值: disabled | clamp | repeat | mirror 其中disabled 是关闭平铺模式,这个也是默认值,开启后,gravity属性会无效,先说下其余三个属性的区别,三种都表示平铺模式

  • repeat表示简单的水平和竖直方向上平铺效果
  • mirror表示一种在水平和竖直方向上的镜面投影效果
  • clamp表示四周像素扩散效果

我们来看下实际的效果:

这里写图片描述

接下来说一下NinePatchDrawable,他说白了就是用代码实现的.9图片而已,我们看一下代码

<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
    android:dither="true"
    android:src="@drawable/ic_launcher">

</nine-patch>

这个就不过多介绍了,基本属性和BitmapDrawable一样,不过现在已经很少有人会用代码去实现了,这样没有图片使用的好

2.ShapeDrawable

ShapeDrawable是一种很常见的Drawable,可以理解为色彩构造的图片,他即是纯色的图形,也可以具有渐变的图形,不过语法要多很多,而且繁杂,我们来看代码的实现:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line">

    <corners
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp"
        android:radius="10dp"
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp" />

    <gradient
        android:angle="10"
        android:centerColor="@color/colorPrimary"
        android:centerX="10"
        android:centerY="10"
        android:endColor="@color/colorPrimary"
        android:gradientRadius="10dp"
        android:startColor="@color/colorAccent"
        android:type="linear"
        android:useLevel="true" />

    <padding
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />

    <size
        android:width="100dp"
        android:height="100dp" />

    <solid android:color="@color/colorAccent" />

    <stroke
        android:width="100dp"
        android:color="@color/colorPrimaryDark"
        android:dashGap="@dimen/activity_horizontal_margin"
        android:dashWidth="10dp" />

</shape>

需要注意的是,shape标签创建的Drawable,实际上是GradientDrawable,我们还是先来分析下他们的属性区别

  • android:shape

表示图片的形状,有四个选项,line(横线),oval(椭圆),rectangle(矩形),ring(圆环),他的默认值是矩形,而且line(横线)和ring(圆环)都必须通过stroke标签来指定宽高,颜色等信息,否则无法达到预期的效果

针对ring的形状,有五个特殊的属性,android:radius,android:tickness,android:innerRadiusRatio,android:ticknessRatio和android:userLevel,我们看图

这里写图片描述

  • < corners>

表示shape的四个角度,它只是用于矩形的shape,这里的角度是指圆角的成都,用px来表示,他有五个属性

  • android:radius:为四个角同时设置相同的角度,优先级较低,会被其他四个覆盖
  • android:topLeftRadius:设置最上角的角度
  • android:topRightRadius:设置右上角的角度
  • android:bottomLeftRadius:设置最下角的角度
  • android:bottomRightRadius:设置右下角的角度

  • < gradient>

他与solid标签是互相排斥的,因为solid表示纯色,而他表示渐变,他的属性如下

  • android:angle:渐变的角度,默认为0,其值必须为45的倍数,0表示从左往右,90表示从上到下,具体的效果自己体验
  • android:centerColor:渐变的中心颜色
  • android:centerX:渐变中心点的横坐标
  • android:centerY:渐变中心点的纵坐标
  • android:endColor:渐变的结束颜色
  • android:gradientRadius:渐变半径,只有当type = radial 时才有效
  • android:startColor:渐变的开始颜色
  • android:type:渐变的类型,
  • android:useLevel:false

  • < solid>

这个标签表示纯色填充,通过android:color来表示填充颜色

  • < stroke>

shape的描边

  • android:width:宽度
  • android:color:颜色
  • android:dashwidth:虚线线段的宽度
  • android:dashGap:组成虚线的线段之间的间隔,间隔越大虚线看起来空隙越大

注意,如果android:dashGap和android:dashwidth有任何一个为0的话,那么虚线就不能生效了,我们来看下效果

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@android:color/white" />

    <stroke
        android:width="2dp"
        android:color="@color/colorPrimary"
        android:dashGap="2dp"
        android:dashWidth="10dp" />

</shape>

这里写图片描述

  • < pading>

这个表示空白,但是他表示的不是shape的空白,而是包含他view的空白,而且有四个属性,左上右下

  • < size>

shape的大小,有两个属性,width/height ,分别表示的是shape的宽高,也可以理解为shape的股友大小,但是一般来说,他并不是最终的大小,这个有点抽象,但是我们要明白,对于shape来说并没有宽高这个概念,作为view的背景他会适应view的宽高,size标签虽然是设置股友大小,但是还是会被拉伸

3.LayerDrawable

LayerDrawable对应的xml是< layer-list>,他可以理解为图层,通过不同的view达到叠加的效果

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/test1"
        android:bottom="5dp"
        android:drawable="@drawable/ic_launcher"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />
    <item
        android:id="@+id/test"
        android:bottom="@dimen/activity_horizontal_margin"
        android:drawable="@drawable/ic_launcher"
        android:left="@dimen/activity_horizontal_margin"
        android:right="@dimen/activity_horizontal_margin"
        android:top="@dimen/activity_horizontal_margin" />

</layer-list>

属性很简单,一个layer-list包含多个item,形成叠加的图层效果,我们可以看一个例子

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#0ac39e" />
        </shape>

    </item>

    <item android:bottom="6dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>
    </item>

    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>

    </item>

</layer-list>

这里写图片描述

4.StateListDrawable

StateListDrawable对应的是< selector>标签,他会根据view的状态来选择出现的drawable,语法如下

<?xml version="1.0" encoding="utf-8"?>
<selector 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:constantSize="true" 
    android:dither="true" 
    android:variablePadding="true">

    <item
        android:drawable="@drawable/ic_launcher"
        android:state_pressed="true"
        android:state_focused="true"
        android:state_hovered="true"
        android:state_selected="true"
        android:state_checkable="true"
        android:state_checked="true"
        android:state_enabled="true"
        android:state_activated="true"
        android:state_window_focused="true" />

</selector>

我们来解释一下上面的属性的意思

  • android:constantSize

StateListDrawable的股友大小是不随其状态的改变发生改变的,因为状态的改变会导致他切换不同的drawable,而不同的drawable具有不同的drawable,true表示StateListDrawable的固有大小不变,这时他的固有大小就是内部所有drawable的固有大小的最大值,false则是跟随状态改变,默认false

  • android:dither

是否开启抖动效果,这个在之前就已经提过,开启此选项可以让图片在低质量的屏幕上显示较好的效果,默认为true

  • android:variablePadding

StateListDrawable的pading是跟随其状态发生改变的而改变,fasle为最大值,跟constantSize类似,不建议开启,默认false

< item>标签标示的是一个具体的Drawable,他的结构也比较简单,其中drawable标示已经资源的id,剩下的就是各种状态了,我们可以看下下面的图

这里写图片描述

下面给出具体的例子

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item 
        android:drawable="@color/colorAccent" 
        android:state_pressed="true" />

    <item 
        android:drawable="@color/colorPrimary" 
        android:state_focused="true" />

    <item 
        android:drawable="@color/colorAccent" />

</selector>

系统会根据View的状态从selector中选择对应的item,每一个对应着一个drawable,系统会按照从上到下来查找,当然,还有默认的drawable

5.LevenlListDrawable

LevenlListDrawable对应着标签,同样表示一个drawable的集合。集合中的每一个Drawable都有一个等级,根据不同的等级切换不同的Item

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@drawable/ic_launcher"
        android:maxLevel="10"
        android:minLevel="1" />

</level-list>

上面的语法中,每一个item代表一个drawable,并且对应着等级范围,由min和max来决定,我们来看一个实际的例子,,当他作为view的背景时,可以通过setLevenl来设置不同的drawable,等级的范围是0-10000

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@color/colorAccent"
        android:maxLevel="0" />
    <item
        android:drawable="@color/colorAccent"
        android:maxLevel="1" />
</level-list>

6.TransitionDrawable

TransitionDrawable对应的是用于实现两个Drawable的淡入淡出

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:bottom="@dimen/activity_horizontal_margin"
        android:drawable="@color/colorAccent"
        android:left="@dimen/activity_horizontal_margin"
        android:right="@dimen/activity_horizontal_margin"
        android:top="@dimen/activity_horizontal_margin" />

</transition>

上面的语法都已经结束过了,我们给出一个实例的例子

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/colorAccent" />
    <item android:drawable="@color/colorPrimary" />
</transition>

接着将上面的设置为View的背景,最后通过startTransition和resetTransition来操作

TransitionDrawable rawable = (TransitionDrawable) iv.getBackground();
drawable.startTransition(1000);

7.InsetDrawable

InsetDrawable对应的是,他可以将其他的Drawable内嵌到自己当中,并且可以在四周留下一定的距离,当一个View想他的背景比实际的距离小的时候就可以用,我们先来看下他的语法

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:insetBottom="@dimen/activity_horizontal_margin"
    android:insetLeft="@dimen/activity_horizontal_margin"
    android:insetRight="@dimen/activity_horizontal_margin"
    android:insetTop="@dimen/activity_horizontal_margin">

</inset>

上面的属性都比较好理解,其中方向就不用说了,我们来看一个实例的例子再说

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="15dp"
    android:insetLeft="15dp"
    android:insetRight="15dp"
    android:insetTop="15dp">

    <shape>
        <solid android:color="@color/colorAccent" />
    </shape>

</inset>

8.ScaleDrawable

ScaleDrawable对应的是,他可以指定自己的等级将指定的Drawable缩放带一定的比例,语法如下

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:scaleGravity="center"
    android:scaleHeight="50%"
    android:scaleWidth="50%">

</scale>

在上门的属性中,scaleGravity的含义等同于shape中的gravity,而这个宽高就是缩放比例,以百分比的形式

ScaleDrawable有点费解,要理解他,我们就要先理解他的等级,0为不可见,要想可见,需要不为0,这个在源码中可以看出来,我们看他的draw方法

    @Override
    public void draw(Canvas canvas) {
        final Drawable d = getDrawable();
        if (d != null && d.getLevel() != 0) {
            d.draw(canvas);
        }
    }

很显然,为0都不会绘制,我们再看一下他的onBoundsChange

    @Override
    protected void onBoundsChange(Rect bounds) {
        final Drawable d = getDrawable();
        final Rect r = mTmpRect;
        final boolean min = mState.mUseIntrinsicSizeAsMin;
        final int level = getLevel();

        int w = bounds.width();
        if (mState.mScaleWidth > 0) {
            final int iw = min ? d.getIntrinsicWidth() : 0;
            w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);
        }

        int h = bounds.height();
        if (mState.mScaleHeight > 0) {
            final int ih = min ? d.getIntrinsicHeight() : 0;
            h -= (int) ((h - ih) * (MAX_LEVEL - level) * mState.mScaleHeight / MAX_LEVEL);
        }

        final int layoutDirection = getLayoutDirection();
        Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);

        if (w > 0 && h > 0) {
            d.setBounds(r.left, r.top, r.right, r.bottom);
        }
    }

在他的onBoundsChange方法中,我们可以看出他的等级和大小,这里拿宽度来说

final int iw = min ? d.getIntrinsicWidth() : 0;
w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);

由于iw一般为0,所以上面的代码其实可以再简化一下 w -=(int)(w*(10000-level)*mState.mScaleWidth /10000),可以发现,级别越大,规律越大,那么内部的Drawable就看起来越大了,我们看一个例子,缩小30%

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:scaleGravity="center"
    android:scaleHeight="30%"
    android:scaleWidth="30%">

</scale>

首先使用上面drawable资源是不行的,还需要设置一下等级

scaleDrawable = (ScaleDrawable) iv.getBackground();
scaleDrawable.setLevel(1);

这个数值小于1000就好

9.ClipDrawable

ClipDrawable对应的是,他可以根据自己的等级裁剪另一个Drawable,裁剪的方法可以通过android:clipOrientation,先看下语法

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/ic_launcher"
    android:gravity="center">

</clip>

其中clipOrientation标示裁剪方向,有水平和竖直,gravity比较复杂,需要和clipOrientation才有作用,我们来看下这张图表

下面我们举个例子来实现一张图片从上往下进行裁剪的效果,那么我们定义一个ClipDrawable

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/ic_launcher"
    android:gravity="bottom">

</clip>

从上面的XML中,因为我们要实现顶部的裁剪效果,所以裁剪的方向是竖直,gravity属性是bottom,那么这个如何使用,设置给ImageView就好了,在代码中

clipDrawable = (ClipDrawable) iv.getBackground();
clipDrawable.setLevel(5000);

三.自定义Drawable

Drawbaled的使用范围很单一,一个座位ImageView在图像的演示,还有就是View的背景,核心就是draw方法

通常我们没有必要去自定义的,因为你无法再xml中使用,下面我们来实现一个过程

public class CustomDrawable extends Drawable {

    private Paint mPaint;

    public CustomDrawable(int color) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(color);
    }

    @Override
    public void draw(Canvas canvas) {
        final Rect f = getBounds();
        float cx = f.exactCenterX();
        float cy = f.exactCenterY();
        canvas.drawCircle(cx, cy, Math.min(cx, cy), mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        invalidateSelf();
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

在上面的代码中,重写了需要实现的几个方法,其中draw是主要的方法,这个方法和View的draw方法类似。而其他三个就比较简单了,这个参靠下shapDrawable的实现就好了,所以说,看源码是很有必要的

这就是本章节的内容了

有兴趣就加群吧:555974449

PPT下载:PPT

Sample下载:Sample

目录
相关文章
|
1月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
266 76
|
5月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
84 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
2月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
218 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
72 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
3月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
174 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
2月前
|
安全 Android开发 iOS开发
escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
escrcpy 是一款基于 Scrcpy 的开源项目,使用 Electron 构建,提供图形化界面来显示和控制 Android 设备。它支持 USB 和 Wi-Fi 连接,帧率可达 30-120fps,延迟低至 35-70ms,启动迅速且画质清晰。escrcpy 拥有丰富的功能,包括自动化任务、多设备管理、反向网络共享、批量操作等,无需注册账号或广告干扰。适用于游戏直播、办公协作和教育演示等多种场景,是一款轻量级、高性能的 Android 控制工具。
121 1
|
3月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
73 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
4月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
97 19
|
4月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
136 14

热门文章

最新文章