Paint的細節用法
1、設定筆帽
mPaint.setStrokeCap(Paint.Cap.BUTT);//沒有
mPaint.setStrokeCap(Paint.Cap.ROUND);//圓形
mPaint.setStrokeCap(Paint.Cap.SQUARE);//方形
2、設定濾鏡
1、模糊遮罩濾鏡(BlurMaskFilter)
2、浮雕遮罩濾鏡(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)
}
橫豎屏切換沉浸式失效
- 查問題時間:3天,問題與window焦點觸摸有關
- 需要效果:在沉浸式模式下,橫屏需要隱藏導航欄,豎屏需要顯示導航欄
- 出現問題:在橫屏,點擊螢屏后導航欄消失,切換為豎屏時,沉浸式效果失效,導航欄消失,只要點擊螢屏即可重新恢復沉浸式
- 解決問題:在沉浸式實作中套一層
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
標籤:其他
