When we are trying to build a custom launcher, we could think about some layout options like grid, scroll view... In this post, we are implementing the grid layout by android default constraint layout.
1. Draw GuideLines
ConstraintLayout containing 5x4 grid with 6x5 guideline
Set constraint like the above picture(percent 0.2, 0.4, etc...) to each of vertical, horizontal lines.
2. Grid Element View
Make Custom Element View composed of upper-side Icon image, lower-side app name.
class AppIconView(context:Context) : View(context) {
private val paint = Paint()
private val iconDrawRegion = Rect()
private lateinit var label: String
lateinit var icon: Bitmap
lateinit var packageName: String
init{
paint.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.NORMAL))
paint.setAntiAlias(true)
}
fun setAppInfo(packageName:String, label:String ,icon:BitmapDrawable){
this.packageName = packageName
this.label = label
this.icon = icon.bitmap
}
override fun onDraw(canvas: Canvas) {
paint.textSize = width/7f
val paddingW = width/5
iconDrawRegion.set(paddingW,paddingW,width-paddingW,width-paddingW)
canvas.drawBitmap(icon,null,iconDrawRegion,paint)
val textDrawSize = paint.measureText(label)
canvas.drawText(label,(width-textDrawSize)/2f,height-(2*paint.textSize),paint)
}
Above code would make a view seems like simple and conventional launcher. For launcher's other behaviors such as drag and drop, We need some additional code that would also be covered by later post.
3. Compose Simple Activity
guideLineV = arrayOf(R.id.guide_v0,R.id.guide_v1,R.id.guide_v2,R.id.guide_v3,R.id.guide_v4)
guideLineH = arrayOf(R.id.guide_h0,R.id.guide_h1,R.id.guide_h2,R.id.guide_h3,R.id.guide_h4,R.id.guide_h5)
layout = findViewById(R.id.my_constraint_layout)
var app_count =0
val filter = Intent(Intent.ACTION_MAIN)
filter.addCategory(Intent.CATEGORY_LAUNCHER)
val allApps = packageManager.queryIntentActivities(filter, 0)
val cs = ConstraintSet()
for (info in allApps) {
val da = AppIconView(this).apply {
id = View.generateViewId()
setAppInfo(info.activityInfo.packageName, info.loadLabel(packageManager).toString() ,info.activityInfo.loadIcon(packageManager) as BitmapDrawable)
val col = app_count % 4
val row = app_count / 4
if(row>4){ // Because we didn't implement tab for multiple appPage, exceeded apps would be just skipped
break
}
apps[row][col] = da
da.col = col
da.row = row
layout.addView(da)
cs.connect(da.id,ConstraintSet.START,guideLineV[col],ConstraintSet.START)
cs.connect(da.id,ConstraintSet.END,guideLineV[col+1],ConstraintSet.START)
cs.connect(da.id,ConstraintSet.TOP,guideLineH[row],ConstraintSet.TOP)
cs.connect(da.id,ConstraintSet.BOTTOM,guideLineH[row+1],ConstraintSet.TOP)
app_count++
}
cs.applyTo(layout)
I referenced this article for getting installed apps for custom launcher. We can insert above code to oncreate method, and it's done.
4. Result
Now, Our view would be seems like below.
No comments:
Post a Comment