主頁 > 移動端開發 > Android開發細節——上班實戰專案中遇到的棘手問題與解決方案匯總

Android開發細節——上班實戰專案中遇到的棘手問題與解決方案匯總

2021-06-13 07:31:59 移動端開發

Paint的細節用法

1、設定筆帽

mPaint.setStrokeCap(Paint.Cap.BUTT);//沒有
mPaint.setStrokeCap(Paint.Cap.ROUND);//圓形
mPaint.setStrokeCap(Paint.Cap.SQUARE);//方形

2、設定濾鏡

1、模糊遮罩濾鏡(BlurMaskFilter2、浮雕遮罩濾鏡(EmbossMaskFilter

3、設定線潭訓合處

mPaint.setStrokeJoin(Paint.Join.MITER);//銳角
mPaint.setStrokeJoin(Paint.Join.ROUND);//圓弧
mPaint.setStrokeJoin(Paint.Join.BEVEL);//直線

這里寫圖片描述

4、文字相關

//獲得字符行間距
mPaint.getFontSpacing();
//獲得字符之間的間距
mPaint.getLetterSpacing();
//設定文本洗掉線
mPaint.setStrikeThruText(true);
//設定下劃線
mPaint.setUnderlineText(true);
//設定文本大小
mPaint.setTextSize(textSize);
//設定字體型別
mPaint.setTypeface(Typeface.ITALIC);
//加載自定義字體
Typeface.create(familyName, style)
//文字傾斜,官方推薦的-0.25f是斜體
mPaint.setTextSkewX(-0.25f);
//文本對齊方式
mPaint.setTextAlign(Align.LEFT);
mPaint.setTextAlign(Align.CENTER);
mPaint.setTextAlign(Align.RIGHT);
//計算制定長度的字串(字符長度、字符個數、真實的長度)
int breadText = mPaint.breakText(text, measureForwards, maxWidth, measuredWidth)
float[] measuredWidth = new float[1];
int breakText = mPaint.breakText(str, true, 200, measuredWidth);
Log.i("TAG", "breakText="+breakText+", str.length()="+str.length()+", measredWidth:"+measuredWidth[0]);
//獲取文本的矩形區域(寬高)
mPaint.getTextBounds(text, index, count, bounds)
//獲取文本的寬度(比較粗略的結果)
float measureText = mPaint.measureText(str);
//獲取文本的寬度(比較精準的)
float[] measuredWidth = new float[10];
int textWidths = mPaint.getTextWidths(str, measuredWidth);
Log.i("TAG", "measureText:"+measureText+", textWidths:"+textWidths);

5、基線相關

FontMetrics fontMetrics = mPaint.getFontMetrics();
//繪制文本在View的左上角(基線Y的計算公式)
float baselineY = top(已知) - fontMetrics.top;
//繪制文本的在View的中間(基線Y的計算公式)
float baselineY = centerY(已知)+ (fontMetrics.bottom-fontMetrics.top)/2 - fontMetrics.bottom;
//繪制文本的在View的中間(或者是這樣的)
float baselineY = centerY(已知)+ (mPaint.descent()+mPaint.ascent())/2;

6、渲染相關

LinearGradient線性渲染
RadialGradient環形渲染、可做水波紋效果,充電水波紋擴散效果、調色板
SweepGradient梯度渲染(掃描渲染)、可做微信等雷達掃描效果
ComposeShader組合渲染

7、ColorMatrix(五階矩陣)

//色彩的平移運算(加法運算)
//色彩的縮放運算(乘法運算)

//構造方法
ColorMatrix matrix = new ColorMatrix(new float[]{});
ColorMatrix matrix = new ColorMatrix();
matrix.set(src)

//設定色彩的縮放函式
matrix.setScale(1, 1, 1.4f, 1);

//設定飽和度(1,是原來不變;0灰色;>1增加飽和度)
matrix.setSaturation(progress);

//色彩旋轉函式(axis,代表繞哪一個軸旋轉,0紅色,1綠色,2藍色,degrees:旋轉的度數)
matrix.setRotate(0, progress);

//ColorFilter使用的子類
ColorMatrixColorFilter:色彩矩陣的顏色顧慮器,
LightingColorFilter:過濾顏色和增強色彩的方法,(光照顏色過濾器)
PorterDuffColorFilter:圖形混合濾鏡(圖形學的一個理論飛躍)

Canvas.drawPath

將文本畫在Path上,可以形成圓弧的文本

Path path = new Path();
//Path.Direction.CW,沿外環;Path.Direction.CCW,沿內環
path.addCircle(500, 500, 200, Path.Direction.CW);
mPaint.setTextSize(50);
// 繪制路徑
canvas.drawPath(path, mPaint);
String text = "大家好,我是Hensen";
canvas.drawTextOnPath(text, path, 0f, 0f, mPaint);

Home鍵回來后會先拉起閃屏的問題

在某些機型上,第一次安裝點擊icon啟動應用,然后home鍵退到后臺,再次點擊icon啟動應用,會先拉起閃屏的問題

class SplashActivity : BaseVMActivity<SplashViewModel>() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        /**
         * 如果此頁面不是任務堆疊中根activity,說明應用有其他activity存在,此時不需要拉起splash頁面,任務堆疊被切到前臺會自動顯示堆疊頂activity
         */
        if (!isTaskRoot) {
            //如果是外部跳轉的Intent也會跑到這里,需要特殊處理
            SchemaUtils.gotoArouter(intent)
            finish()
            return
        }
        setContentView(R.layout.activity_splash)
    }
}

java.lang.NoSuchMethodError

在我們崩潰系統中會看到這種崩潰

java.lang.NoSuchMethodError: No static method Desc(I)Ljava/lang/String; in class Lcom/yy/platform/baseservice/ConstCode$SrvResCode; or its super classes (declaration of 'com.yy.platform.baseservice.ConstCode$SrvResCode' appears in /data/app/com.yy.yinfu-0eluUMz7kO0sb_RhAZpHNw==/split_lib_dependencies_apk.apk!classes2.dex)

從崩潰的日志上翻譯出來的意思是,找不到該類的方法,但是又在classes2.dex發現了這個類的方法,這是因為在多Dex的情況下,我們啟動需要的class都需要放在maindex中,由于這個類放在了classes2.dex,所以報出找不到的崩潰,由于我們是Debug包,所以不加處理,但是在Release包中我們對混淆過后的這個類放在maindex中

release {
    ......
    multiDexKeepProguard file('multidex.keep')
    ......
}

multidex.keep中加入我們找不到的class即可

-keep class com.xxx.xxx.xxx$xxxx

Fragment嵌套SurfaceView切換時閃黑屏

最近在開發的時候用的是ViewPager+Fragment進行底部Tab頁的切換,但在最后一個Tab中Fragment嵌入了SurfaceView,用于Flutter開發,不料在切換Tab的時候SurfaceView的Tab會導致其他Tab切換過去的時候顯示黑屏或者白屏等情況(黑屏、白屏主要取決你設定的Theme),解決方法是在SurfaceView上進行這兩句話設定

setZOrderOnTop(true);    
setZOrderMediaOverlay(true);
mHolder.setFormat(PixelFormat.TRANSPARENT);

RecyclerView實作點擊拖拽而不是長按拖拽

最近做專案,需要在3張圖片中,左右拖動能更換位置,再此,封裝了一個左右拖拽的輔助類,將RecyclerView設定不能左右滑動,但是點擊就能左右拖動Item,并交換左右圖片

class ListeningKonwPeopleRecyclerViewController(var context: Context,
                                                var recyclerView: RecyclerView,
                                                var data: ArrayList<LisnteningKonwPeopleInfo>) {

    var helper: ItemTouchHelper? = null
    var adapter: ListeningKonwPeopleCoverAdapter? = null
    var layoutManager: LinearLayoutManager? = null

    init {
        layoutManager = object : LinearLayoutManager(context, HORIZONTAL, false) {
            override fun canScrollHorizontally(): Boolean {
                return false
            }
        }

        adapter = ListeningKonwPeopleCoverAdapter(data)
        recyclerView.layoutManager = layoutManager
        recyclerView.adapter = adapter

        helper = ItemTouchHelper(
                object : ItemTouchHelper.Callback() {
                    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
                        val dragFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT//拖拽
                        return ItemTouchHelper.Callback.makeMovementFlags(dragFlags, 0)
                    }

                    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
                        //滑動事件
                        Collections.swap(data, viewHolder.adapterPosition, target.adapterPosition)
                        adapter?.notifyItemMoved(viewHolder.adapterPosition, target.adapterPosition)
                        return false
                    }

                    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                        //側滑事件
                    }

                    override fun isLongPressDragEnabled(): Boolean {
                        return false
                    }
                })
        helper?.attachToRecyclerView(recyclerView)
    }

    fun attach() {
        adapter?.setOnTouchClickListener(
                object : ListeningKonwPeopleCoverAdapter.OnTouchClickListener {
                    override fun onTouchClick(info: LisnteningKonwPeopleInfo, holder: ListeningKonwPeopleCoverAdapter.VH) {
                        helper?.startDrag(holder)
                    }
                })
    }

    fun dettach() {
        adapter?.setOnTouchClickListener(
                object : ListeningKonwPeopleCoverAdapter.OnTouchClickListener {
                    override fun onTouchClick(info: LisnteningKonwPeopleInfo, holder: ListeningKonwPeopleCoverAdapter.VH) {
                        return
                    }
                })
    }
}

Adapter中設定OnTouchClickListener的實作

override fun onBindViewHolder(holder: VH, position: Int) {
    ......
    
    holder.itemView.setOnTouchListener { v, event ->
        if (event.action == MotionEvent.ACTION_DOWN) {
            mOnTouchClickListener?.onTouchClick(info, holder)
        }
        return@setOnTouchListener false
    }
}

使用點擊拖拽功能

activity?.let {
    recyclerViewController = ListeningKonwPeopleRecyclerViewController(it, view.rv_cover, data)
    recyclerViewController?.attach()
}

取消點擊拖拽功能

activity?.let {
    recyclerViewController = ListeningKonwPeopleRecyclerViewController(it, view.rv_cover, data)
    recyclerViewController?.dettach()
}

鍵盤彈起不會頂上去視圖

鍵盤彈起要讓視圖跟著彈起解決方案太多,但是有個比較簡單的方案,可以適合大多數場景,這場適合于鍵盤蓋住視圖的情況下使用,在蓋住的布局中使用android:fitsSystemWindows="true"即可

<com.yy.mobile.memoryrecycle.views.YYLinearLayout
        android:id="@+id/input_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/common_color_11"
        android:fitsSystemWindows="true"
        android:gravity="center"
        android:minHeight="@dimen/moment_chat_input_height"
        android:orientation="vertical"
        android:visibility="gone">

為什么View.startAnimation不起作用?

看了一下View里面的原始碼,發現確實有一些地方判斷了如果不是visible的,那么就不呼叫invalidate方法,也就不會去處理Animation的事情,以后startAnimation的時候,—定要選─個總是可見的View哦

正確的用法

private fun startShowAnimation(from: AnimationFrom,
                               animationView: View,
                               centerX: Float,
                               centerY: Float) {
    animationView.visibility = View.VISIBLE
    val scaleAnimation = ScaleAnimation(0f, 1f, 0f, 1f, centerX, centerY)
    scaleAnimation.duration = 250
    scaleAnimation.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationRepeat(animation: Animation?) {
        }

        override fun onAnimationEnd(animation: Animation?) {
        }

        override fun onAnimationStart(animation: Animation?) {
        }
    })
    animationView.startAnimation(scaleAnimation)
}

橫豎屏切換沉浸式失效

  1. 查問題時間:3天,問題與window焦點觸摸有關
  2. 需要效果:在沉浸式模式下,橫屏需要隱藏導航欄,豎屏需要顯示導航欄
  3. 出現問題:在橫屏,點擊螢屏后導航欄消失,切換為豎屏時,沉浸式效果失效,導航欄消失,只要點擊螢屏即可重新恢復沉浸式
  4. 解決問題:在沉浸式實作中套一層getWindow().getDecorView().post(new Runnable() {}即可解決
private void initImmersive() {
    if (isLandscape()) {
        //增加沉浸式
        ImmersionBar.with(this)
                .navigationBarEnable(false)
                .transparentStatusBar()
                .statusBarDarkFont(false)
                .init();
        //橫屏需要隱藏底部導航欄
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                if (!checkActivityValid()) {
                    return;
                }
                if (getContext() instanceof Activity && NavBarUtils.hasNavBar(getContext())) {
                    NavBarUtils.hideBottomNav((Activity) getContext());
                }
            }
        });
    } else {
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                if (!checkActivityValid()) {
                    return;
                }
                if (getContext() instanceof Activity) {
                    //增加沉浸式
                    ImmersionBar.with((Activity) getContext())
                            .navigationBarEnable(false)
                            .transparentStatusBar()
                            .statusBarDarkFont(false)
                            .init();
                }
            }
        });
    }
}

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

標籤:其他

上一篇:Android第十四講筆記(廣播,百度地圖)

下一篇:紀行:FileProvider沖突問題解決

標籤雲
其他(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