diff --git a/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt b/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt index 7037d03..439cb78 100644 --- a/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt +++ b/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt @@ -2,21 +2,22 @@ package com.finnmglas.launcher import android.app.Activity import android.content.Intent -import android.graphics.Color -import android.net.Uri import android.os.Bundle import android.view.View import android.view.WindowManager -import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.finnmglas.launcher.choose.AppsRecyclerAdapter import com.finnmglas.launcher.extern.* import kotlinx.android.synthetic.main.activity_choose.* class ChooseActivity : AppCompatActivity() { - /** Activity Lifecycle functions */ + private lateinit var viewAdapter: RecyclerView.Adapter<*> + private lateinit var viewManager: RecyclerView.LayoutManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -42,57 +43,32 @@ class ChooseActivity : AppCompatActivity() { // As older APIs somehow do not recognize the xml defined onClick activity_choose_close.setOnClickListener() { finish() } + // get info about which action this activity is open for val bundle = intent.extras val action = bundle!!.getString("action") // why choose an app val forApp = bundle.getString("forApp") // which app we choose - if (action == "launch") - activity_choose_heading.text = getString(R.string.choose_title_launch) - else if (action == "pick") - activity_choose_heading.text = getString(R.string.choose_title) - else if (action == "uninstall") - activity_choose_heading.text = getString(R.string.choose_title_remove) + when (action) { + "launch" -> activity_choose_heading.text = getString(R.string.choose_title_launch) + "pick" -> activity_choose_heading.text = getString(R.string.choose_title) + "uninstall" -> activity_choose_heading.text = getString(R.string.choose_title_remove) + } - /* Build Layout */ + // set up the list / recycler + viewManager = LinearLayoutManager(this) + viewAdapter = AppsRecyclerAdapter( this, action, forApp) - for (resolveInfo in appsList) { - val app = resolveInfo.activityInfo - - // creating TextView programmatically - val tvdynamic = TextView(this) - tvdynamic.textSize = 24f - tvdynamic.text = app.loadLabel(packageManager).toString() - tvdynamic.setTextColor(Color.parseColor("#cccccc")) - - if (action == "launch"){ - tvdynamic.setOnClickListener { startActivity(packageManager.getLaunchIntentForPackage(app.packageName)) } - } - else if (action == "pick"){ - tvdynamic.setOnClickListener { - val returnIntent = Intent() - returnIntent.putExtra("value", app.packageName) - returnIntent.putExtra("forApp", forApp) - setResult( - REQUEST_CHOOSE_APP, - returnIntent - ) - finish() - } - } - else if (action == "uninstall"){ - tvdynamic.setOnClickListener { - val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) - intent.data = Uri.parse("package:" + app.packageName) - intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) - startActivityForResult(intent, - REQUEST_UNINSTALL - ) - } - } - activity_choose_apps_list.addView(tvdynamic) + activity_choose_apps_recycler_view.apply { + // improve performance (since content changes don't change the layout size) + setHasFixedSize(true) + layoutManager = viewManager + adapter = viewAdapter } } + /* + }*/ + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_UNINSTALL) { diff --git a/app/src/main/java/com/finnmglas/launcher/choose/AppInfo.kt b/app/src/main/java/com/finnmglas/launcher/choose/AppInfo.kt new file mode 100644 index 0000000..801a43c --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/choose/AppInfo.kt @@ -0,0 +1,9 @@ +package com.finnmglas.launcher.choose + +import android.graphics.drawable.Drawable + +class AppInfo { + var label: CharSequence? = null + var packageName: CharSequence? = null + var icon: Drawable? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/finnmglas/launcher/choose/AppsRecyclerAdapter.kt b/app/src/main/java/com/finnmglas/launcher/choose/AppsRecyclerAdapter.kt new file mode 100644 index 0000000..78ef583 --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/choose/AppsRecyclerAdapter.kt @@ -0,0 +1,93 @@ +package com.finnmglas.launcher.choose + +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import android.widget.Toast +import androidx.recyclerview.widget.RecyclerView +import com.finnmglas.launcher.R +import com.finnmglas.launcher.extern.* + + +class AppsRecyclerAdapter(val activity: Activity, val action: String?, val forApp: String?): + RecyclerView.Adapter() { + + private val appsList: MutableList + + inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), + View.OnClickListener { + var textView: TextView = itemView.findViewById(R.id.choose_row_app_name) + var img: ImageView = itemView.findViewById(R.id.choose_row_app_icon) as ImageView + + override fun onClick(v: View) { + val pos = adapterPosition + val context: Context = v.context + val appPackageName = appsList[pos].packageName.toString() + + when (action){ + "launch" -> { + val launchIntent: Intent = context.packageManager + .getLaunchIntentForPackage(appPackageName)!! + context.startActivity(launchIntent) + Toast.makeText(v.context, appsList[pos].label.toString(), Toast.LENGTH_LONG) + .show() + } + "pick" -> { + val returnIntent = Intent() + returnIntent.putExtra("value", appPackageName) + returnIntent.putExtra("forApp", forApp) + activity.setResult(REQUEST_CHOOSE_APP, returnIntent) + activity.finish() + } + "uninstall" -> { + val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE) + intent.data = Uri.parse("package:$appPackageName") + intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) + activity.startActivityForResult(intent, REQUEST_UNINSTALL) + } + } + } + + init { itemView.setOnClickListener(this) } + } + + override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) { + val appLabel = appsList[i].label.toString() + val appPackage = appsList[i].packageName.toString() + val appIcon = appsList[i].icon + val textView = viewHolder.textView + textView.text = appLabel + val imageView: ImageView = viewHolder.img + imageView.setImageDrawable(appIcon) + } + + override fun getItemCount(): Int { return appsList.size } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + val view: View = inflater.inflate(R.layout.recycler_apps_row, parent, false) + return ViewHolder(view) + } + + init { + val pm: PackageManager = activity.packageManager + appsList = ArrayList() + val i = Intent(Intent.ACTION_MAIN, null) + i.addCategory(Intent.CATEGORY_LAUNCHER) + val allApps = pm.queryIntentActivities(i, 0) + for (ri in allApps) { + val app = AppInfo() + app.label = ri.loadLabel(pm) + app.packageName = ri.activityInfo.packageName + app.icon = ri.activityInfo.loadIcon(pm) + appsList.add(app) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_choose.xml b/app/src/main/res/layout/activity_choose.xml index e15028a..911d0cd 100644 --- a/app/src/main/res/layout/activity_choose.xml +++ b/app/src/main/res/layout/activity_choose.xml @@ -58,25 +58,19 @@ - - - - + app:layout_constraintTop_toBottomOf="@id/activity_choose_app_bar" /> \ No newline at end of file diff --git a/app/src/main/res/layout/recycler_apps_row.xml b/app/src/main/res/layout/recycler_apps_row.xml new file mode 100644 index 0000000..f981ccd --- /dev/null +++ b/app/src/main/res/layout/recycler_apps_row.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file