Merge "Move click handler from XML to ViewModel (1/2)" into tm-qpr-dev am: 28aa7dd51f am: 56ee6b5ca0

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19398174

Change-Id: I63e87db2603a15c240844f7c6200ad6586229524
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jordan Demeulenaere
2022-07-26 10:18:57 +00:00
committed by Automerger Merge Worker
4 changed files with 57 additions and 48 deletions

View File

@@ -54,7 +54,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/rounded_bg_full_large_radius"
android:onClick="dismissActivity"
android:text="@string/got_it"
android:textColor="?androidprv:attr/textColorOnAccent"
android:layout_marginBottom="60dp"

View File

@@ -22,7 +22,6 @@ import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.activity.ComponentActivity;
@@ -40,7 +39,6 @@ public class PeopleSpaceActivity extends ComponentActivity {
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private final PeopleViewModel.Factory mViewModelFactory;
private PeopleViewModel mViewModel;
@Inject
public PeopleSpaceActivity(PeopleViewModel.Factory viewModelFactory) {
@@ -52,38 +50,32 @@ public class PeopleSpaceActivity extends ComponentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED);
mViewModel = new ViewModelProvider(this, mViewModelFactory).get(PeopleViewModel.class);
PeopleViewModel viewModel = new ViewModelProvider(this, mViewModelFactory).get(
PeopleViewModel.class);
// Update the widget ID coming from the intent.
int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
mViewModel.onWidgetIdChanged(widgetId);
viewModel.onWidgetIdChanged(widgetId);
ViewGroup view = PeopleViewBinder.create(this);
PeopleViewBinder.bind(view, mViewModel, /* lifecycleOwner= */ this,
() -> {
finishActivity();
PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this,
(result) -> {
finishActivity(result);
return null;
});
setContentView(view);
}
/** Finish activity with a successful widget configuration result. */
private void finishActivity() {
if (DEBUG) Log.d(TAG, "Widget added!");
setActivityResult(RESULT_OK);
private void finishActivity(PeopleViewModel.Result result) {
if (result instanceof PeopleViewModel.Result.Success) {
if (DEBUG) Log.d(TAG, "Widget added!");
Intent data = ((PeopleViewModel.Result.Success) result).getData();
setResult(RESULT_OK, data);
} else {
if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
setResult(RESULT_CANCELED);
}
finish();
}
/** Finish activity without choosing a widget. */
public void dismissActivity(View v) {
if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
setResult(RESULT_CANCELED);
finish();
}
private void setActivityResult(int result) {
Intent resultValue = new Intent();
resultValue.putExtra(EXTRA_APPWIDGET_ID, mViewModel.getAppWidgetId().getValue());
setResult(result, resultValue);
}
}

View File

@@ -41,7 +41,7 @@ import kotlinx.coroutines.launch
/** A ViewBinder for [PeopleViewModel]. */
object PeopleViewBinder {
private const val TAG = "PeopleSpaceViewBinder"
private const val TAG = "PeopleViewBinder"
/**
* The [ViewOutlineProvider] used to clip the corner radius of the recent and priority lists.
@@ -72,15 +72,15 @@ object PeopleViewBinder {
view: ViewGroup,
viewModel: PeopleViewModel,
lifecycleOwner: LifecycleOwner,
onFinish: () -> Unit,
onResult: (PeopleViewModel.Result) -> Unit,
) {
// Call [onFinish] this activity when the ViewModel tells us so.
// Call [onResult] as soon as a result is available.
lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(CREATED) {
viewModel.isFinished.collect { isFinished ->
if (isFinished) {
viewModel.clearIsFinished()
onFinish()
viewModel.result.collect { result ->
if (result != null) {
viewModel.clearResult()
onResult(result)
}
}
}
@@ -104,7 +104,7 @@ object PeopleViewBinder {
viewModel::onTileClicked,
)
} else {
setNoConversationsContent(view)
setNoConversationsContent(view, viewModel::onUserJourneyCancelled)
}
}
}
@@ -119,7 +119,7 @@ object PeopleViewBinder {
}
}
private fun setNoConversationsContent(view: ViewGroup) {
private fun setNoConversationsContent(view: ViewGroup, onGotItClicked: () -> Unit) {
// This should never happen.
if (view.childCount > 1) {
error("view has ${view.childCount} children, it should have maximum 1")
@@ -140,6 +140,10 @@ object PeopleViewBinder {
LayoutInflater.from(context)
.inflate(R.layout.people_space_activity_no_conversations, /* root= */ view)
noConversationsView.findViewById<View>(R.id.got_it_button).setOnClickListener {
onGotItClicked()
}
// The Tile preview has colorBackground as its background. Change it so it's different than
// the activity's background.
val item = noConversationsView.findViewById<LinearLayout>(android.R.id.background)

View File

@@ -16,8 +16,10 @@
package com.android.systemui.people.ui.viewmodel
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
@@ -32,6 +34,7 @@ import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/**
* Models UI state for the people space, allowing the user to select which conversation should be
@@ -49,7 +52,7 @@ class PeopleViewModel(
* reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
*/
private val _priorityTiles = MutableStateFlow(priorityTiles())
val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles
val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles.asStateFlow()
/**
* The list of the priority tiles/conversations.
@@ -58,15 +61,15 @@ class PeopleViewModel(
* reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
*/
private val _recentTiles = MutableStateFlow(recentTiles())
val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles
val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles.asStateFlow()
/** The ID of the widget currently being edited/added. */
private val _appWidgetId = MutableStateFlow(INVALID_APPWIDGET_ID)
val appWidgetId: StateFlow<Int> = _appWidgetId
val appWidgetId: StateFlow<Int> = _appWidgetId.asStateFlow()
/** Whether the user journey is complete. */
private val _isFinished = MutableStateFlow(false)
val isFinished: StateFlow<Boolean> = _isFinished
/** The result of this user journey. */
private val _result = MutableStateFlow<Result?>(null)
val result: StateFlow<Result?> = _result.asStateFlow()
/** Refresh the [priorityTiles] and [recentTiles]. */
fun onTileRefreshRequested() {
@@ -79,22 +82,28 @@ class PeopleViewModel(
_appWidgetId.value = widgetId
}
/** Clear [isFinished], setting it to false. */
fun clearIsFinished() {
_isFinished.value = false
/** Clear [result], setting it to null. */
fun clearResult() {
_result.value = null
}
/** Called when a tile is clicked. */
fun onTileClicked(tile: PeopleTileViewModel) {
val widgetId = _appWidgetId.value
if (PeopleSpaceUtils.DEBUG) {
Log.d(
TAG,
"Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID: " +
_appWidgetId.value
"Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID $widgetId"
)
}
widgetRepository.setWidgetTile(_appWidgetId.value, tile.key)
_isFinished.value = true
widgetRepository.setWidgetTile(widgetId, tile.key)
_result.value =
Result.Success(Intent().apply { putExtra(EXTRA_APPWIDGET_ID, appWidgetId.value) })
}
/** Called when this user journey is cancelled. */
fun onUserJourneyCancelled() {
_result.value = Result.Cancelled
}
private fun priorityTiles(): List<PeopleTileViewModel> {
@@ -143,7 +152,12 @@ class PeopleViewModel(
}
}
sealed class Result {
class Success(val data: Intent) : Result()
object Cancelled : Result()
}
companion object {
private const val TAG = "PeopleSpaceViewModel"
private const val TAG = "PeopleViewModel"
}
}