Feat: Added work profile support with icon.

Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
This commit is contained in:
HeCodes2Much
2024-05-28 21:41:44 +01:00
parent bbe9c98464
commit e61a9894b2
12 changed files with 161 additions and 32 deletions

View File

@@ -14,6 +14,7 @@ import android.graphics.drawable.AdaptiveIconDrawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.UserHandle import android.os.UserHandle
import android.os.UserManager
import android.provider.AlarmClock import android.provider.AlarmClock
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.Settings import android.provider.Settings
@@ -297,6 +298,16 @@ fun Context.searchCustomSearchEngine(searchQuery: String? = null): Boolean {
return true return true
} }
fun Context.isWorkProfileEnabled(): Boolean {
val userManager = getSystemService(Context.USER_SERVICE) as? UserManager
return if (userManager != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val profiles = userManager.userProfiles
profiles.size > 1
} else {
false
}
}
fun Context.backupSharedPreferences(backupFileName: String) { fun Context.backupSharedPreferences(backupFileName: String) {
val sharedPreferences: SharedPreferences = val sharedPreferences: SharedPreferences =
this.getSharedPreferences(Constants.PREFS_FILENAME, 0) this.getSharedPreferences(Constants.PREFS_FILENAME, 0)

View File

@@ -17,7 +17,7 @@ interface AppInfoDAO {
suspend fun update(app: AppInfo) suspend fun update(app: AppInfo)
@Delete @Delete
suspend fun delete(app: AppInfo) fun delete(app: AppInfo)
@Query("SELECT * FROM app ORDER BY app_name COLLATE NOCASE ASC") @Query("SELECT * FROM app ORDER BY app_name COLLATE NOCASE ASC")
fun getAllApps(): List<AppInfo> fun getAllApps(): List<AppInfo>
@@ -73,9 +73,12 @@ interface AppInfoDAO {
@Query("SELECT * FROM app WHERE is_favorite = 1") @Query("SELECT * FROM app WHERE is_favorite = 1")
fun getFavoriteAppInfo(): List<AppInfo> fun getFavoriteAppInfo(): List<AppInfo>
@Query("SELECT * FROM app WHERE package_name = :packageName") @Query("SELECT * FROM app WHERE package_name = :packageName AND is_work = 0")
suspend fun getAppByPackageName(packageName: String): AppInfo? suspend fun getAppByPackageName(packageName: String): AppInfo?
@Query("SELECT * FROM app WHERE package_name = :packageName AND is_work = 1")
suspend fun getAppByPackageNameWork(packageName: String): AppInfo?
private fun logUpdate(message: String, appInfo: AppInfo) { private fun logUpdate(message: String, appInfo: AppInfo) {
// You can replace this with a logging library like Timber for more advanced logging capabilities. // You can replace this with a logging library like Timber for more advanced logging capabilities.
Log.d( Log.d(

View File

@@ -26,8 +26,11 @@ data class AppInfo(
@ColumnInfo(name = "is_lock") @ColumnInfo(name = "is_lock")
var lock: Boolean, var lock: Boolean,
@ColumnInfo(name = "is_work")
var work: Boolean,
@ColumnInfo(name = "create_time") @ColumnInfo(name = "create_time")
var createTime: String = "", var createTime: String,
@ColumnInfo(name = "app_order") @ColumnInfo(name = "app_order")
var appOrder: Int = -1 var appOrder: Int = -1

View File

@@ -85,8 +85,8 @@ internal open class OnSwipeTouchListener(c: Context?) : OnTouchListener {
if (diffY < 0) onSwipeUp() else onSwipeDown() if (diffY < 0) onSwipeUp() else onSwipeDown()
} }
} }
} catch (exception: Exception) { } catch (exception: NullPointerException) {
exception.printStackTrace() return false
} }
return false return false
} }

View File

@@ -3,8 +3,11 @@ package com.github.droidworksstudio.launcher.repository
import android.content.Context import android.content.Context
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build
import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi
import com.github.droidworksstudio.launcher.Constants import com.github.droidworksstudio.launcher.Constants
import com.github.droidworksstudio.launcher.data.dao.AppInfoDAO import com.github.droidworksstudio.launcher.data.dao.AppInfoDAO
import com.github.droidworksstudio.launcher.data.entities.AppInfo import com.github.droidworksstudio.launcher.data.entities.AppInfo
@@ -12,11 +15,13 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.lang.reflect.Method
import java.time.LocalDateTime
import javax.inject.Inject import javax.inject.Inject
class AppInfoRepository @Inject constructor( class AppInfoRepository @Inject constructor(
private val appDao: AppInfoDAO private val appDao: AppInfoDAO,
) { ) {
@Inject @Inject
@@ -98,7 +103,9 @@ class AppInfoRepository @Inject constructor(
packages packages
} }
suspend fun initInstalledAppInfo(context: Context): List<AppInfo> = withContext(Dispatchers.IO) { @RequiresApi(Build.VERSION_CODES.O)
suspend fun initInstalledAppInfo(context: Context): List<AppInfo> =
withContext(Dispatchers.IO) {
val appList: MutableList<AppInfo> = mutableListOf() val appList: MutableList<AppInfo> = mutableListOf()
val allApps = appDao.getAllAppsFlow().firstOrNull() val allApps = appDao.getAllAppsFlow().firstOrNull()
@@ -109,29 +116,69 @@ class AppInfoRepository @Inject constructor(
val launcherApps = val launcherApps =
context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val excludedPackageNames = mutableListOf(Constants.PACKAGE_NAME,Constants.PACKAGE_NAME_DEBUG) val excludedPackageNames =
mutableListOf(Constants.PACKAGE_NAME, Constants.PACKAGE_NAME_DEBUG)
val getIdentifierMethod: Method =
UserHandle::class.java.getDeclaredMethod("getIdentifier")
val newAppList: List<AppInfo> = userManager.userProfiles val newAppList: List<AppInfo> = userManager.userProfiles
.flatMap { profile -> .flatMap { profile ->
launcherApps.getActivityList(null, profile) // Invoke the getIdentifier method on the UserHandle instance
.mapNotNull { app -> val userId = getIdentifierMethod.invoke(profile) as Int
val packageName = app.applicationInfo.packageName
if (packageName !in existingPackageNames && packageName !in excludedPackageNames) { when (userId) {
AppInfo( 0 -> {
appName = app.label.toString(), // Handle the case when profile is UserHandle{0}
packageName = packageName, launcherApps.getActivityList(null, profile)
favorite = false, .mapNotNull { app ->
hidden = false, val packageName = app.applicationInfo.packageName
lock = false val currentDateTime = LocalDateTime.now()
) if (packageName !in existingPackageNames && packageName !in excludedPackageNames) {
} else { AppInfo(
val existingApp = getAppByPackageName(packageName) appName = app.label.toString(),
existingApp?.let { appList.add(it) } packageName = packageName,
existingApp favorite = false,
} hidden = false,
lock = false,
createTime = currentDateTime.toString(),
work = false,
)
} else {
val existingApp = getAppByPackageName(packageName)
existingApp?.let { appList.add(it) }
existingApp
}
}
} }
else -> {
// Handle other profiles
launcherApps.getActivityList(null, profile)
.mapNotNull { app ->
val packageName = app.applicationInfo.packageName
val currentDateTime = LocalDateTime.now()
if (packageName !in existingPackageNames && packageName !in excludedPackageNames) {
AppInfo(
appName = app.label.toString(),
packageName = packageName,
favorite = false,
hidden = false,
lock = false,
createTime = currentDateTime.toString(),
work = true,
)
} else {
val existingApp = getAppByPackageNameWork(packageName)
existingApp?.let { appList.add(it) }
existingApp
}
}
}
}
} }
appDao.insertAll(newAppList.sortedBy { it.appName }) appDao.insertAll(newAppList.sortedBy { it.appName })
Log.d("Tag", "State: ${newAppList.sortedBy { it.appName }}") Log.d("Tag", "State: ${newAppList.sortedBy { it.appName }}")
@@ -142,6 +189,7 @@ class AppInfoRepository @Inject constructor(
appList appList
} }
@RequiresApi(Build.VERSION_CODES.R)
suspend fun compareInstalledApp(): List<AppInfo> = withContext(Dispatchers.IO) { suspend fun compareInstalledApp(): List<AppInfo> = withContext(Dispatchers.IO) {
val installedPackages = getInstalledPackages() val installedPackages = getInstalledPackages()
val uninstalledApps = mutableListOf<AppInfo>() val uninstalledApps = mutableListOf<AppInfo>()
@@ -176,4 +224,8 @@ class AppInfoRepository @Inject constructor(
private suspend fun getAppByPackageName(packageName: String): AppInfo? { private suspend fun getAppByPackageName(packageName: String): AppInfo? {
return appDao.getAppByPackageName(packageName) return appDao.getAppByPackageName(packageName)
} }
private suspend fun getAppByPackageNameWork(packageName: String): AppInfo? {
return appDao.getAppByPackageNameWork(packageName)
}
} }

View File

@@ -1,16 +1,14 @@
package com.github.droidworksstudio.launcher.ui.activities package com.github.droidworksstudio.launcher.ui.activities
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager
import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController import androidx.navigation.NavController
@@ -19,7 +17,6 @@ import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp import androidx.navigation.ui.navigateUp
import com.github.droidworksstudio.ktx.isTablet import com.github.droidworksstudio.ktx.isTablet
import com.github.droidworksstudio.launcher.Constants
import com.github.droidworksstudio.launcher.R import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.databinding.ActivityMainBinding import com.github.droidworksstudio.launcher.databinding.ActivityMainBinding
import com.github.droidworksstudio.launcher.helper.AppHelper import com.github.droidworksstudio.launcher.helper.AppHelper
@@ -68,6 +65,7 @@ class MainActivity : AppCompatActivity() {
} }
@RequiresApi(Build.VERSION_CODES.R)
private fun setupDataBase() { private fun setupDataBase() {
lifecycleScope.launch { lifecycleScope.launch {
viewModel.initializeInstalledAppInfo(this@MainActivity) viewModel.initializeInstalledAppInfo(this@MainActivity)
@@ -118,6 +116,7 @@ class MainActivity : AppCompatActivity() {
|| super.onSupportNavigateUp() || super.onSupportNavigateUp()
} }
@RequiresApi(Build.VERSION_CODES.R)
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
backToHomeScreen() backToHomeScreen()

View File

@@ -37,7 +37,6 @@ class DrawAdapter(
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val appInfo = getItem(position) val appInfo = getItem(position)
(holder as DrawViewHolder).bind(appInfo) (holder as DrawViewHolder).bind(appInfo)
} }

View File

@@ -2,6 +2,7 @@ package com.github.droidworksstudio.launcher.ui.drawer
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.Spannable import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
@@ -10,6 +11,7 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
@@ -64,7 +66,13 @@ class DrawFragment : Fragment(),
private val viewModel: AppViewModel by viewModels() private val viewModel: AppViewModel by viewModels()
private val drawAdapter: DrawAdapter by lazy { DrawAdapter(this, this, preferenceHelper) } private val drawAdapter: DrawAdapter by lazy {
DrawAdapter(
this,
this,
preferenceHelper
)
}
private lateinit var context: Context private lateinit var context: Context
override fun onCreateView( override fun onCreateView(
@@ -98,6 +106,7 @@ class DrawFragment : Fragment(),
} }
} }
@RequiresApi(Build.VERSION_CODES.R)
private fun observeDrawerApps() { private fun observeDrawerApps() {
viewModel.compareInstalledAppInfo() viewModel.compareInstalledAppInfo()
@@ -242,12 +251,14 @@ class DrawFragment : Fragment(),
binding.searchViewText.hideKeyboard() binding.searchViewText.hideKeyboard()
} }
@RequiresApi(Build.VERSION_CODES.R)
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
observeDrawerApps() observeDrawerApps()
if (preferenceHelper.automaticKeyboard) binding.searchViewText.showKeyboard() if (preferenceHelper.automaticKeyboard) binding.searchViewText.showKeyboard()
} }
@RequiresApi(Build.VERSION_CODES.R)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
observeDrawerApps() observeDrawerApps()

View File

@@ -1,8 +1,14 @@
package com.github.droidworksstudio.launcher.ui.drawer package com.github.droidworksstudio.launcher.ui.drawer
import android.util.Log import android.util.Log
import android.view.Gravity
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.LinearLayoutCompat import androidx.appcompat.widget.LinearLayoutCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.droidworksstudio.ktx.dpToPx
import com.github.droidworksstudio.ktx.isWorkProfileEnabled
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.data.entities.AppInfo import com.github.droidworksstudio.launcher.data.entities.AppInfo
import com.github.droidworksstudio.launcher.databinding.ItemDrawBinding import com.github.droidworksstudio.launcher.databinding.ItemDrawBinding
import com.github.droidworksstudio.launcher.helper.PreferenceHelper import com.github.droidworksstudio.launcher.helper.PreferenceHelper
@@ -14,7 +20,9 @@ class DrawViewHolder(
private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener, private val onAppLongClickedListener: OnItemClickedListener.OnAppLongClickedListener,
private val preferenceHelper: PreferenceHelper private val preferenceHelper: PreferenceHelper
) : ) :
RecyclerView.ViewHolder(binding.root) { RecyclerView.ViewHolder(binding.root) {
fun bind(appInfo: AppInfo) { fun bind(appInfo: AppInfo) {
binding.apply { binding.apply {
val layoutParams = LinearLayoutCompat.LayoutParams( val layoutParams = LinearLayoutCompat.LayoutParams(
@@ -30,7 +38,28 @@ class DrawViewHolder(
appDrawName.text = appInfo.appName appDrawName.text = appInfo.appName
appDrawName.setTextColor(preferenceHelper.appColor) appDrawName.setTextColor(preferenceHelper.appColor)
appDrawName.textSize = preferenceHelper.appTextSize appDrawName.textSize = preferenceHelper.appTextSize
Log.d("Tag", "Draw Adapter: ${appInfo.appName + appInfo.id}") Log.d("Tag", "Draw Adapter: ${appInfo.appName + appInfo.id} | ${appInfo.work}")
val icon = AppCompatResources.getDrawable(appDrawName.context, R.drawable.work_profile)
val px = preferenceHelper.appTextSize.toInt().dpToPx()
icon?.setBounds(0, 0, px, px)
if (appInfo.work) {
val appLabelGravity = preferenceHelper.homeAppAlignment
if (appLabelGravity == Gravity.START) {
appDrawName.setCompoundDrawables(icon, null, null, null)
} else {
appDrawName.setCompoundDrawables(null, null, icon, null)
}
appDrawName.compoundDrawablePadding = 20
if (!appDrawName.context.isWorkProfileEnabled()) {
appDrawName.visibility = View.GONE
}
} else {
// If appInfo.work is false, remove the drawable
appDrawName.setCompoundDrawables(null, null, null, null)
appDrawName.compoundDrawablePadding = 0
}
} }
itemView.setOnClickListener { itemView.setOnClickListener {

View File

@@ -1,7 +1,9 @@
package com.github.droidworksstudio.launcher.viewmodel package com.github.droidworksstudio.launcher.viewmodel
import android.content.Context import android.content.Context
import android.os.Build
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.github.droidworksstudio.launcher.data.entities.AppInfo import com.github.droidworksstudio.launcher.data.entities.AppInfo
@@ -22,47 +24,58 @@ class AppViewModel @Inject constructor(
val drawApps: Flow<List<AppInfo>> = appInfoRepository.getDrawApps().conflate() val drawApps: Flow<List<AppInfo>> = appInfoRepository.getDrawApps().conflate()
val favoriteApps: Flow<List<AppInfo>> = appInfoRepository.getFavoriteApps().conflate() val favoriteApps: Flow<List<AppInfo>> = appInfoRepository.getFavoriteApps().conflate()
val hiddenApps: Flow<List<AppInfo>> = appInfoRepository.getHiddenApps().conflate() val hiddenApps: Flow<List<AppInfo>> = appInfoRepository.getHiddenApps().conflate()
@RequiresApi(Build.VERSION_CODES.R)
fun initializeInstalledAppInfo(context: Context) { fun initializeInstalledAppInfo(context: Context) {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.initInstalledAppInfo(context) appInfoRepository.initInstalledAppInfo(context)
} }
} }
fun updateAppInfoFavorite(appInfo: AppInfo) { fun updateAppInfoFavorite(appInfo: AppInfo) {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.updateFavoriteAppInfo(appInfo) appInfoRepository.updateFavoriteAppInfo(appInfo)
Log.d("Tag", "ViewModel Home Order : ${appInfo.appOrder}") Log.d("Tag", "ViewModel Home Order : ${appInfo.appOrder}")
} }
} }
fun updateAppInfoAppName(appInfo: AppInfo, newAppName: String) { fun updateAppInfoAppName(appInfo: AppInfo, newAppName: String) {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.updateAppName(appInfo, newAppName) appInfoRepository.updateAppName(appInfo, newAppName)
Log.d("Tag", "ViewModel Home Name : ${appInfo.appName}") Log.d("Tag", "ViewModel Home Name : ${appInfo.appName}")
} }
} }
fun updateAppHidden(appInfo: AppInfo, appHidden: Boolean) { fun updateAppHidden(appInfo: AppInfo, appHidden: Boolean) {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.updateAppHidden(appInfo, appHidden) appInfoRepository.updateAppHidden(appInfo, appHidden)
} }
} }
fun updateAppLock(appInfo: AppInfo, appLock: Boolean) { fun updateAppLock(appInfo: AppInfo, appLock: Boolean) {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.updateAppLock(appInfo, appLock) appInfoRepository.updateAppLock(appInfo, appLock)
} }
} }
@RequiresApi(Build.VERSION_CODES.R)
fun compareInstalledAppInfo() { fun compareInstalledAppInfo() {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.compareInstalledApp() appInfoRepository.compareInstalledApp()
} }
} }
suspend fun updateAppOrder(appInfoList: List<AppInfo>) { suspend fun updateAppOrder(appInfoList: List<AppInfo>) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
appInfoRepository.updateAppOrder(appInfoList) appInfoRepository.updateAppOrder(appInfoList)
} }
} }
fun update(appInfo: AppInfo) { fun update(appInfo: AppInfo) {
viewModelScope.launch { viewModelScope.launch {
appInfoRepository.updateInfo(appInfo) appInfoRepository.updateInfo(appInfo)
} }
} }
fun searchAppInfo(query: String?) = appInfoRepository.searchNote(query) fun searchAppInfo(query: String?) = appInfoRepository.searchNote(query)
} }

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40sp"
android:height="40sp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:fillColor="@android:color/white"
android:pathData="M6.542,36.292Q4.708,36.292 3.438,35.021Q2.167,33.75 2.167,31.917V13.292Q2.167,11.458 3.438,10.188Q4.708,8.917 6.542,8.917H12.25V5.583Q12.25,3.75 13.521,2.479Q14.792,1.208 16.625,1.208H23.375Q25.208,1.208 26.479,2.479Q27.75,3.75 27.75,5.583V8.917H33.458Q35.292,8.917 36.583,10.188Q37.875,11.458 37.875,13.292V31.917Q37.875,33.75 36.583,35.021Q35.292,36.292 33.458,36.292ZM6.542,31.917H33.458Q33.458,31.917 33.458,31.917Q33.458,31.917 33.458,31.917V13.292Q33.458,13.292 33.458,13.292Q33.458,13.292 33.458,13.292H6.542Q6.542,13.292 6.542,13.292Q6.542,13.292 6.542,13.292V31.917Q6.542,31.917 6.542,31.917Q6.542,31.917 6.542,31.917ZM16.625,8.917H23.375V5.583Q23.375,5.583 23.375,5.583Q23.375,5.583 23.375,5.583H16.625Q16.625,5.583 16.625,5.583Q16.625,5.583 16.625,5.583ZM6.542,31.917Q6.542,31.917 6.542,31.917Q6.542,31.917 6.542,31.917V13.292Q6.542,13.292 6.542,13.292Q6.542,13.292 6.542,13.292Q6.542,13.292 6.542,13.292Q6.542,13.292 6.542,13.292V31.917Q6.542,31.917 6.542,31.917Q6.542,31.917 6.542,31.917Z" />
</vector>

View File

@@ -53,7 +53,7 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/drawAdapter" android:id="@+id/drawAdapter"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/search_view_text" /> app:layout_constraintTop_toBottomOf="@id/search_view_text" />