主頁 > 移動端開發 > 深入了解一些Android影片

深入了解一些Android影片

2020-09-11 12:14:18 移動端開發

一、PropertyValuesHolder

閱讀本文需要上一文Android屬性影片的基礎,這樣才可以明白接下來要講什么,

1.理解和使用

PropertyValuesHolder 是ObjectAnimation類似的一個方法,只是少了一個target,就是要執行的控制元件,看看正常的使用方法:會同時執行全部的Holder

public void  doPropertyValuesHolder(){
        //定義一個旋轉Holder
        PropertyValuesHolder rotationHolder=
                PropertyValuesHolder.ofFloat(
                        "rotation",
                        60f,40f,100f,-60f,40f,88f,77f);

        //定義一個透明Holder
        PropertyValuesHolder alphaHolder=
                PropertyValuesHolder.ofFloat(
                        "alpha",
                        0.01f,0.5f,1.0f,0.8f,0.2f,0.0f);
        
    	//加載進ObjectAnimator
        ObjectAnimator objectAnimator=ObjectAnimator.ofPropertyValuesHolder(ballImageView,rotationHolder,alphaHolder);
        objectAnimator.setDuration(3000);
        objectAnimator.start();
    }

2.方法和引數

可以看看這個方法的引數:

ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)
PropertyValuesHolder ofFloat(String propertyName, float... values)

Object target 是要顯示影片的控制元件

PropertyValuesHolder... values 裝載多個PropertyValuesHolder

String propertyName 代表要反射的引數,跟ObjectAnimation的引數是一樣的

float... values 代表是可變長引數
這樣的方法還有以下圖片這些:

圖片.png

其中ofObject()方法 ,也是跟ObjectAnimation的相似,也是要自定義TypeEvaluator,
圖片.png

二、Keyframe

1.理解和使用

看名字,就是理解為關鍵幀的意思,在影片中,在某幀做一些操作,從而實作對比效果比較明顯的效果,
關鍵幀表示是某個物體在哪個時間點應該在哪個位置上,
具體使用:

 public void  doPropertyValuesHolderKeyFrame(){

        //頭keyframe1,從進度0.6開始,在進度60%的時候,數值是0.1f
        Keyframe keyframe1=Keyframe.ofFloat(0.6f,0.1f);

        //中間keyframe2
        Keyframe keyframe2=Keyframe.ofFloat(0.1f,0.8f);

        //尾部keyframe3,以50%進度作為結束,這時候的數值為0.2f
        Keyframe keyframe3=Keyframe.ofFloat(0.5f,0.2f);

        //裝載到Holder中,并設定要反射的方法,這是反射的是setAlpha()方法,控制透明度
        PropertyValuesHolder alphaHolder=PropertyValuesHolder.ofKeyframe("alpha",keyframe1,keyframe2,keyframe3);

        //把裝載到Holder中裝載到ObjectAnimator或者ValueAnimation
        ObjectAnimator objectAnimator=ObjectAnimator.ofPropertyValuesHolder(ballImageView,alphaHolder);
        objectAnimator.setDuration(3000);
        objectAnimator.start();
    }

2.方法和引數

Keyframe ofFloat(float fraction, float value)

float fraction 表示進度

float value 表示在這個進度下的數值

 PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)

String propertyName 要反射的set方法

Keyframe... values 傳入Keyframe

Keyframe的方法,也是和其他的類似的,
圖片.png

Keyframe的set方法,設定進度,插值器,數值,
沒有設定插值器的時候,默認是線性插值器

 keyframe1.setInterpolator(new LinearInterpolator()); //默認線性插值器

圖片.png

3.幀的操作

直接寫結論:

  • 如果去掉0幀,則以第一個關鍵幀為起始位置
  • 如果去掉結束幀(進度為1),則以最后一個關鍵幀為結束位置
  • 使用keyframe來構建影片,至少需要2幀

三、ViewPropertyAnimator

1.理解和使用

可以通過串行的形式,快速定義影片,省去一些定義,在每次界面繪制的時候,啟動影片,比其他的更節省消耗,
比如:

 ballImageView.animate().alpha(0.5f).rotation(360f).scaleX(1.5f).translationX(100f);

2.引數和方法

可以看到這些方法的回傳值,基本都是ViewPropertyAnimator
圖片.png
圖片.png
再參考一張表格:

函式 含義
alpha(float value) 設定透明度
scaleY(float value) 設定 Y軸方向的縮放大小
scaleX(float value) 設定X軸方向的縮放大小
translationY(float value) 設定Y軸方向的移動值
translationX(float value) 設定X軸方向的移動值
rotation(float value) 設定繞Z軸旋轉度數
rotationX(float value) 設定繞x軸旋轉度數
rotationY(float value) 設定繞 Y 軸旋轉度數
x(float value) 相對于父容器的左上角坐標在 X軸方向的最終位置
y(float value) 相對于父容器的左上角坐標在Y軸方向的最終位置
alphaBy(float value) 設定透明度增量
rotationBy(float value) 設定繞Z軸旋轉增量
rotationXBy(float value) 設定繞 X 油旋轉增量
rotationYBy(float value) 設定統Y軸旋轉增量
translationXBy(float value) 設定X軸方向的移動值增量
translationYBy(float value) 設定Y軸方向的移動值增量
scaleXBy(float value) 設定X軸方向的縮放大小增量
scaleYBy(float value) 設定 Y軸方向的縮放大小增量
xBy(float value) 相對于父容器的左上角坐標在 X軸方向的位置增量
yBy(float value) 相對于父容器的左上角坐標在 Y軸方向的位置增量
setlnterpolator(Timelnterpolator interpolator) 設定插值器
setStartDelay(long startDelay) 設定開始延時
setDuration(long duration) 設定影片時長

四、animateLayoutChanges

android:animateLayoutChanges="true"
在Layout加入控制元件,或者移除控制元件的時候,添加影片,但是只能使用默認影片,

 <LinearLayout
            android:animateLayoutChanges="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"/>

五、LayoutTransition

LayoutTransition可以控制ViewGroup的影片,可以使用自定義的影片,
具體使用:

 public void doLayoutTransition(){

        LinearLayout linearLayout=new LinearLayout(this);

        //1.創建實體
        LayoutTransition transition=new LayoutTransition();

        //2.創建影片
        ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(null,"rotation",0f,90f,0f);

        //3.影片出現形式進行設定
        transition.setAnimator(LayoutTransition.DISAPPEARING,objectAnimator);

        //4.將LayoutTransition設定到ViewGroup中
        linearLayout.setLayoutTransition(transition);
     
      	//5.開源影片庫 NineOldAndroids
     
    }

setAnimator(int transitionType, Animator animator)

這個方法中,transitionType有五個選項

image.png

CHANGE_APPEARING 由于容器中要顯示一個新的元素,其他需要變化的元素所應用的影片(問題多,不常用)

_CHANGE_DISAPPEARING_ 當個容器中某個元素要消失時,其他需要變化的元素所應用的影片(問題多,不常用)

_CHANGING_ 容器中正在更改的元素的影片變化

_APPEARING_ 元素在容器中出現時所定義的影片

_DISAPPEARING_ 元素在容器中消失時所定義的影片

六、PathMeasure

PathMeasure類似一個計算器,可以計算出目標path的坐標,長度等

1.初始化

  public void doPathMeasure(){
        Path path=new Path();

        //初始化方法1
        PathMeasure pathMeasure1=new PathMeasure();
        pathMeasure1.setPath(path,true);

        //初始化方法2
        PathMeasure pathMeasure2=new PathMeasure(path,false);
    }

setPath(Path path, boolean forceClosed)
path 就是代表要計算的目標Path,
forceClosed 是否閉合,true會計算閉合狀態下的Path,false會按照Path原來情況來計算,

2.函式呼叫

自定義一個view

public class PathView extends View {
    Path mPath;
    Paint mPaint;
    PathMeasure mPathMeasure;

    public PathView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPath=new Path();
        mPaint=new Paint();
        mPathMeasure=new PathMeasure();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.translate(250,250); //畫布移動
        mPaint.setColor(Color.BLUE); //畫筆顏色
        mPaint.setStrokeWidth(5); //畫筆粗細
        mPaint.setStyle(Paint.Style.STROKE); //畫筆風格

        mPath.moveTo(0,0);
        mPath.lineTo(0,100);
        mPath.lineTo(100,100);
        mPath.lineTo(100,0);

        mPathMeasure.setPath(mPath,true);
        Log.v("showLog",
                "getLength()=="+mPathMeasure.getLength()
                        +"  isClosed()=="+ mPathMeasure.isClosed()); //結果400.0  true

        mPathMeasure.setPath(mPath,false);
        Log.v("showLog",
                "getLength()=="+mPathMeasure.getLength()
                        +"  isClosed()=="+ mPathMeasure.isClosed()); //結果300.0  false

        canvas.drawPath(mPath,mPaint); //繪制路徑
    }
}

繪制效果:

image.png

2.1 PathMeasure.getLength()

PathMeasure.getLength() 函式用于測量路徑的長度

2.2 PathMeasure.isClosed()

PathMeasure.isClosed() 函式用于回傳是否測量閉合狀態

2.3 PathMeasure.nextContour()

   		mPath.addRect(-50, -50, 50, 50, Path.Direction.CW);
        canvas.drawPath(mPath, mPaint);

        mPath.addRect(-100, -100, 100, 100, Path.Direction.CW);
        canvas.drawPath(mPath, mPaint);

        mPath.addRect(-120, -120, 120, 120, Path.Direction.CW);
        canvas.drawPath(mPath, mPaint);

        mPathMeasure.setPath(mPath, false);

        do {
            float len = mPathMeasure.getLength();
            Log.v("showLog", "len=" + len);
        } while (mPathMeasure.nextContour());

效果:

image.png

列印結果:

len=400.0
len=800.0
len=960.0

PathMeasure.nextContour()得到的順序與添加的Path的順序相同

PathMeasure.getLength()只是得到當前path的長度,不是全部的長度

2.3 getSegment()

使用getSegment函式需要禁用硬體加速 在構造方法中加入
setLayerType(LAYER_TYPE_SOFTWARE,null);

 		mPath.addRect(-50, -50, 50, 50, Path.Direction.CW);
        mPathMeasure.setPath(mPath,false); //計算的path
        mPathMeasure.getSegment(0,150,mDstPath,true); //截取并添加到mDstPath,是添加,不是其他
        canvas.drawPath(mPath, mPaint); //繪制原來的path

        canvas.translate(200,0); //畫布移動
        mPaint.setColor(Color.RED);
        canvas.drawPath(mDstPath, mPaint); //繪制添加后的mDstPath
 boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)

startD path開始截取的點,截取的起始點,是以左上角的點開始的

stopD 截取停止的點

dst 截取后添加到的path

startWithMoveTo 是否保存原狀,true保存原樣,false則會連接初始點和終點,和原來的不一定相同形狀
以上代碼的效果: 截圖的方向,與原來的path的生成方向有關

image.png

2.4 動態畫圓的例子

代碼:


public class PathView extends View {
    Path mPath, mDstPath;
    Paint mPaint;
    PathMeasure mPathMeasure;
    float mCurAnimValue;

    public PathView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mPath = new Path();
        mDstPath = new Path();
        mPaint = new Paint();
        mPathMeasure = new PathMeasure();

        mPaint.setColor(Color.BLUE); //畫筆顏色
        mPaint.setStrokeWidth(5); //畫筆粗細
        mPaint.setStyle(Paint.Style.STROKE); //畫筆風格

        mPath.addCircle(100, 100, 50, Path.Direction.CW); //一個完整的圓
        mPathMeasure.setPath(mPath, true); //要計算的path

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1); //進度 0~1
        animator.setRepeatCount(ValueAnimator.INFINITE); //無限回圈
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurAnimValue = https://www.cnblogs.com/lanjiabin/p/(Float) animation.getAnimatedValue(); //得到當前的進度
                invalidate();//重繪,重新執行onDraw()方法
            }
        });
        animator.setDuration(5000);
        animator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(100, 100); //畫布移動

        float stop=mPathMeasure.getLength()*mCurAnimValue; //一個進度確定一個截取點
        mDstPath.reset();
        mPathMeasure.getSegment(0,stop,mDstPath,true); //一點點添加

        canvas.drawPath(mDstPath,mPaint); //每次有進度更新,就繪制一小段截取
    }
}

效果:
動態畫圓.gif

2.5 getPosTan()

先看看函式的定義:

boolean getPosTan(float distance, float pos[], float tan[]) 

float distance 距離path的其實長度

float pos[] 該點的坐標值,x和y pos[0]=x,pos[1]=y

float tan[] 該點的正切值,x和y pos[0]=x,pos[1]=y tan<a=y/x

2.6 箭頭畫圓的例子

代碼:


public class PathView extends View {
    Path mPath, mDstPath;
    Paint mPaint;
    PathMeasure mPathMeasure;
    float mCurAnimValue;
    Bitmap mArrowBmp;
    float[] mPos;
    float[] mTan;
    int mCenterX,mCenterY;
    float mRadius;

    public PathView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mPath = new Path();
        mDstPath = new Path();
        mPaint = new Paint();
        mPathMeasure = new PathMeasure();
        mPos=new float[2];
        mTan=new float[2];

        //加載箭頭圖片
        mArrowBmp= BitmapFactory.decodeResource(getResources(), R.drawable.arrow);

        mPaint.setColor(Color.BLUE); //畫筆顏色
        mPaint.setStrokeWidth(5); //畫筆粗細
        mPaint.setStyle(Paint.Style.STROKE); //畫筆風格

        mPath.addCircle(540, 972, 486, Path.Direction.CW); //一個完整的圓
        mPathMeasure.setPath(mPath, true); //要計算的path

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1); //進度 0~1
        animator.setRepeatCount(ValueAnimator.INFINITE); //無限回圈
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurAnimValue = https://www.cnblogs.com/lanjiabin/p/(Float) animation.getAnimatedValue(); //得到當前的進度
                invalidate();//重繪,重新執行onDraw()方法
            }
        });
        animator.setDuration(5000);
        animator.start();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        /*
         * 得到h,w的最小的那個值;
         * >> 1 移位 跟 /2 相同;
         * 乘以0.9f,表示占布局的90%
         * */
        mRadius = (Math.min(h, w) >> 1) * 0.9f;

        // 中心坐標
        mCenterX = w / 2;
        mCenterY = h / 2;
        Log.v("showLog",mCenterX+"  "+mCenterY+"  "+mRadius);
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float stop=mPathMeasure.getLength()*mCurAnimValue; //一個進度確定一個截取點

        mDstPath.reset();
        mPathMeasure.getSegment(0,stop,mDstPath,true); //一點點添加

        canvas.drawPath(mDstPath,mPaint); //每次有進度更新,就繪制一小段截取

        mPathMeasure.getPosTan(stop,mPos,mTan); //獲得每點的正切值和坐標

        /**
         *    Math.atan2(mTan[1],mTan[0])獲得tan的弧度值
         *    *180.0/Math.PI將轉化為角度值
         * */
        float degrees=(float)(Math.atan2(mTan[1],mTan[0])*180.0/Math.PI);

        Matrix matrix=new Matrix();

        /**
         * 將圖片圍繞中心點旋轉指定角度
         * postRotate(float degrees, float px, float py)
         * degrees是角度  (px,py)是圖片中心點
         * */
        matrix.postRotate(degrees,mArrowBmp.getWidth()/2,mArrowBmp.getHeight()/2);

        /**
         * 將圖片從默認的(0,0)點移動到路徑的最前端
         * */
        matrix.postTranslate(mPos[0]-mArrowBmp.getWidth()/2,mPos[1]-mArrowBmp.getHeight()/2);

        //繪制圖片
        canvas.drawBitmap(mArrowBmp,matrix,mPaint);

    }
}

效果:

箭頭動態畫圓.gif

2.7 getMatrix()

引數型別:

boolean getMatrix(float distance, Matrix matrix, int flags)

使用方法:

  		//計算方位角
        Matrix matrix = new Matrix();

		//獲取位置資訊
        mPathMeasure.getMatrix(stop,matrix,PathMeasure.POSITION_MATRIX_FLAG);

		//獲取切邊資訊
        mPathMeasure.getMatrix(stop,matrix,PathMeasure.TANGENT_MATRIX_FLAG); 

2.8 支付成功例子

public class TickView extends View {
    Path mPath, mDstPath;
    Paint mPaint;
    PathMeasure mPathMeasure;
    float mCurAnimValue;
    int mCenterX, mCenterY;
    float mRadius;

    public TickView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mPath = new Path();
        mDstPath = new Path();
        mPaint = new Paint();
        mPathMeasure = new PathMeasure();

        mPaint.setColor(Color.BLUE); //畫筆顏色
        mPaint.setStrokeWidth(5); //畫筆粗細
        mPaint.setStyle(Paint.Style.STROKE); //畫筆風格

        mCenterX = 540;
        mCenterY = 972;
        mRadius = 486 / 2;

        /**
         * 圓
         * */
        mPath.addCircle(mCenterX, mCenterY, mRadius, Path.Direction.CW);

        /**
         * 對勾
         * */
        mPath.moveTo(mCenterX - mRadius / 2, mCenterY);
        mPath.lineTo(mCenterX, mCenterY + mRadius / 2);
        mPath.lineTo(mCenterX + mRadius / 2, mCenterY - mRadius / 3);

        mPathMeasure.setPath(mPath, false); //要計算的path

        ValueAnimator animator = ValueAnimator.ofFloat(0, 2); //進度 0~1 是圓,1~2是對勾
        animator.setRepeatCount(ValueAnimator.RESTART);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurAnimValue = https://www.cnblogs.com/lanjiabin/p/(Float) animation.getAnimatedValue(); //得到當前的進度
                invalidate();//重繪,重新執行onDraw()方法
            }
        });
        animator.setDuration(5000);
        animator.start();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        /*
         * 得到h,w的最小的那個值;
         * >> 1 移位 跟 /2 相同;
         * 乘以0.9f,表示占布局的90%
         * */
        mRadius = (Math.min(h, w) >> 1) * 0.9f;

        // 中心坐標
        mCenterX = w / 2;
        mCenterY = h / 2;
        Log.v("showLog", mCenterX + "  " + mCenterY + "  " + mRadius);
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mCurAnimValue < 1) {
            float stop = mPathMeasure.getLength() * mCurAnimValue;
            mPathMeasure.getSegment(0, stop, mDstPath, true);
        } else if (mCurAnimValue == 1) {
            mPathMeasure.getSegment(0, mPathMeasure.getLength(), mDstPath, true);
            mPathMeasure.nextContour();
        } else {
            float stop = mPathMeasure.getLength() * (mCurAnimValue - 1);
            mPathMeasure.getSegment(0, stop, mDstPath, true);
        }

        canvas.drawPath(mDstPath, mPaint);
    }
}

效果:
對勾影片.gif

編程中我們會遇到多少挫折?表放棄,沙漠盡頭必是綠洲,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/5580.html

標籤:Android

上一篇:CtsSecurityTestCases#ListeningPortsTest定位tcp埠與pid

下一篇:iOS核心影片高級技巧 - 7

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more