欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android-architecture:TO-DO-MVVM-Lifecycles解析

程序员文章站 2022-03-16 12:42:15
...

GitHub:https://github.com/googlesamples/android-architecture/tree/todo-mvvm-live/

架构图

android-architecture:TO-DO-MVVM-Lifecycles解析

LAUNCHER

android-architecture:TO-DO-MVVM-Lifecycles解析

TasksActivity

<activity
            android:name="com.example.android.architecture.blueprints.todoapp.tasks.TasksActivity"
            android:theme="@style/AppTheme.OverlapSystemBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

TasksActivity.java
TasksActivity extends AppCompatActivity

tasks_act.xml
DrawerLayout(
    LinearLayout(
        AppBarLayout(
            Toolbar
        )
        CoordinatorLayout(
            FrameLayout
            FloatingActionButton
        )
    )
    NavigationView
)

1. onCreate:
    1. 获取TasksViewModel.java
        public static TasksViewModel obtainViewModel(FragmentActivity activity) {
            // Use a Factory to inject dependencies into the ViewModel
            ViewModelFactory factory = ViewModelFactory.getInstance(activity.getApplication());
            TasksViewModel viewModel =
                    ViewModelProviders.of(activity, factory).get(TasksViewModel.class);
            return viewModel;
        }
    2. 添加LiveData感知
        // Subscribe to "open task" event  fragment -> 过来的数据
        mViewModel.getOpenTaskEvent().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String taskId) {
                if (taskId != null) {
                    openTaskDetails(taskId);
                }
            }
        });
        // Subscribe to "new task" event
        mViewModel.getNewTaskEvent().observe(this, new Observer<Void>() {
            @Override
            public void onChanged(@Nullable Void _) {
                addNewTask();
            }
        });
    3. 设置要显示的Fragment
        private void setupViewFragment() {
            //检测该contentFrame是否添加过
            TasksFragment tasksFragment =
                    (TasksFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);
            if (tasksFragment == null) {
                // Create the fragment
                tasksFragment = TasksFragment.newInstance();
                ActivityUtils.replaceFragmentInActivity(
                        getSupportFragmentManager(), tasksFragment, R.id.contentFrame);
            }
        }
    4. 其他 ...

TasksFragment

1. tasks_frag.xml
    Android Studio 开启 
        dataBinding {
            enabled = true
        }
    会生成相应的Binding管理对象
    ->TasksFragBinding.java
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <!--变量-->
        <variable
            name="viewmodel"
            type="com.example.android.architecture.blueprints.todoapp.tasks.TasksViewModel" />
    </data>
    <com.example.android.architecture.blueprints.todoapp.ScrollChildSwipeRefreshLayout
        android:id="@+id/refresh_layout"
        ...
        android:onRefresh="@{viewmodel}"
        app:refreshing="@{viewmodel.dataLoading}">
        <RelativeLayout
            android:id="@+id/tasksContainer"
            ...>
            <LinearLayout
                android:id="@+id/tasksLL"
                ...
                android:visibility="@{viewmodel.empty ? View.GONE : View.VISIBLE}">
                <TextView
                    android:id="@+id/filteringLabel"
                    ...
                    android:text="@{viewmodel.currentFilteringLabel}"
                    />
                <ListView
                    android:id="@+id/tasks_list"
                    ...
                    app:items="@{viewmodel.items}" />
            </LinearLayout>
            <!-- 中间提示-->
            <LinearLayout
                android:id="@+id/noTasks"
                ...
                android:visibility="@{viewmodel.empty ? View.VISIBLE : View.GONE}">
                <ImageView
                    android:id="@+id/noTasksIcon"
                    ...
                    android:src="@{viewmodel.noTaskIconRes}" />
                <TextView
                    android:id="@+id/noTasksMain"
                    ...
                    android:text="@{viewmodel.noTasksLabel}" />
                <TextView
                    android:id="@+id/noTasksAdd"
                    ...
                    android:onClick="@{() -> viewmodel.addNewTask()}"
                    android:visibility="@{viewmodel.tasksAddViewVisible ? View.VISIBLE : View.GONE}" />
            </LinearLayout>
        </RelativeLayout>
    </com.example.android.architecture.blueprints.todoapp.ScrollChildSwipeRefreshLayout>
</layout>   

2. TasksFragment.java
    public class TasksFragment extends Fragment {}

    1. onCreateView:
        // 绑定 View 与 ViewModel
        @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mTasksFragBinding = TasksFragBinding.inflate(inflater, container, false);
        mTasksViewModel = TasksActivity.obtainViewModel(getActivity());
        // 向View 设置 ViewModel
        mTasksFragBinding.setViewmodel(mTasksViewModel);
        ...
        //从 TasksFragBinding.inflate 中获取 layout
        return mTasksFragBinding.getRoot();
    }
    2. onActivityCreated:
        // 添加LiveData感知
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            setupSnackbar();
            setupFab();
            setupListAdapter();
            setupRefreshLayout();
        }

        private void setupSnackbar() {
            // 设置 Snackbar 的感知,当数据改变时会显示 snackbar
            mTasksViewModel.getSnackbarMessage().observe(this, new SnackbarMessage.SnackbarObserver() {
                @Override
                public void onNewMessage(@StringRes int snackbarMessageResourceId) {
                    SnackbarUtils.showSnackbar(getView(), getString(snackbarMessageResourceId));
                }
            });
        }

        private void setupFab() {
            FloatingActionButton fab =
                    (FloatingActionButton) getActivity().findViewById(R.id.fab_add_task);
            fab.setImageResource(R.drawable.ic_add);
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 触发事件
                    mTasksViewModel.addNewTask();
                    /*
                        public void addNewTask() {
                            mNewTaskEvent.call();
                        }
                    */
                }
            });
        }
        // 绑定 ListView
        private void setupListAdapter() {
            // 获取 android:id="@+id/tasks_list" 
            ListView listView = mTasksFragBinding.tasksList;
            mListAdapter = new TasksAdapter(
                    new ArrayList<Task>(0),
                    mTasksViewModel
            );
            listView.setAdapter(mListAdapter);
        }
        // 绑定 SwipeRefreshLayout
        private void setupRefreshLayout() {
            //android:id="@+id/tasks_list"
            ListView listView = mTasksFragBinding.tasksList;
            //android:id="@+id/refresh_layout"
            final ScrollChildSwipeRefreshLayout swipeRefreshLayout = mTasksFragBinding.refreshLayout;
            swipeRefreshLayout.setColorSchemeColors(
                    ContextCompat.getColor(getActivity(), R.color.colorPrimary),
                    ContextCompat.getColor(getActivity(), R.color.colorAccent),
                    ContextCompat.getColor(getActivity(), R.color.colorPrimaryDark)
            );
            // Set the scrolling view in the custom SwipeRefreshLayout.
            swipeRefreshLayout.setScrollUpChild(listView);
        }
    2. onResume:
        //加载数据
        @Override
        public void onResume() {
            super.onResume();
            mTasksViewModel.start();
        }

android-architecture:TO-DO-MVVM-Lifecycles解析
android-architecture:TO-DO-MVVM-Lifecycles解析
android-architecture:TO-DO-MVVM-Lifecycles解析

相关标签: MVVM