36 | * It's possible to vary this with list device size, but often unnecessary, unless a user 37 | * scrolling on a large device is expected to scroll through items more quickly than a small 38 | * device, such as when the large device uses a grid layout of items. 39 | */ 40 | private const val PAGE_SIZE = 30 41 | 42 | /** 43 | * If placeholders are enabled, PagedList will report the full size but some items might 44 | * be null in onBind method (PagedListAdapter triggers a rebind when data is loaded). 45 | *
46 | * If placeholders are disabled, onBind will never receive null but as more pages are 47 | * loaded, the scrollbars will jitter as new pages are loaded. You should probably disable 48 | * scrollbars if you disable placeholders. 49 | */ 50 | private const val ENABLE_PLACEHOLDERS = true 51 | } 52 | 53 | val allCheeses = LivePagedListBuilder(dao.allCheesesByName(), PagedList.Config.Builder() 54 | .setPageSize(PAGE_SIZE) 55 | .setEnablePlaceholders(ENABLE_PLACEHOLDERS) 56 | .build()).build() 57 | 58 | fun insert(text: CharSequence) = ioThread { 59 | dao.insert(Cheese(id = 0, name = text.toString())) 60 | } 61 | 62 | fun remove(cheese: Cheese) = ioThread { 63 | dao.delete(cheese) 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/lilingzhi/llvr/paging/CheeseAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.lilingzhi.llvr.paging 18 | 19 | import android.arch.paging.PagedListAdapter 20 | import android.support.v7.util.DiffUtil 21 | import android.view.ViewGroup 22 | 23 | /** 24 | * A simple PagedListAdapter that binds Cheese items into CardViews. 25 | *
26 | * PagedListAdapter is a RecyclerView.Adapter base class which can present the content of PagedLists 27 | * in a RecyclerView. It requests new pages as the user scrolls, and handles new PagedLists by 28 | * computing list differences on a background thread, and dispatching minimal, efficient updates to 29 | * the RecyclerView to ensure minimal UI thread work. 30 | *
31 | * If you want to use your own Adapter base class, try using a PagedListAdapterHelper inside your
32 | * adapter instead.
33 | *
34 | * @see android.arch.paging.PagedListAdapter
35 | * @see android.arch.paging.AsyncPagedListDiffer
36 | */
37 | class CheeseAdapter : PagedListAdapter
50 | * When you add a Cheese with the 'Add' button, the PagedListAdapter uses diffCallback to
51 | * detect there's only a single item difference from before, so it only needs to animate and
52 | * rebind a single view.
53 | *
54 | * @see android.support.v7.util.DiffUtil
55 | */
56 | private val diffCallback = object : DiffUtil.ItemCallback
20 | * Cheeses are stored in a database, so swipes and additions edit the database directly, and the UI
21 | * is updated automatically using paging components.
22 | */
23 | class PagingActivity : AppCompatActivity() {
24 | private val viewModel by lazy(LazyThreadSafetyMode.NONE) {
25 | ViewModelProviders.of(this).get(CheeseViewModel::class.java)
26 | }
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | setContentView(R.layout.activity_paging)
31 |
32 | // Create adapter for the RecyclerView
33 | val adapter = CheeseAdapter()
34 | cheeseList.adapter = adapter
35 |
36 | // Subscribe the adapter to the ViewModel, so the items in the adapter are refreshed
37 | // when the list changes
38 | viewModel.allCheeses.observe(this, Observer(adapter::submitList))
39 |
40 | initAddButtonListener()
41 | initSwipeToDelete()
42 |
43 | getSupportActionBar()!!.setTitle("Paging");
44 | }
45 |
46 | private fun initSwipeToDelete() {
47 | ItemTouchHelper(object : ItemTouchHelper.Callback() {
48 | // enable the items to swipe to the left or right
49 | override fun getMovementFlags(recyclerView: RecyclerView,
50 | viewHolder: RecyclerView.ViewHolder): Int =
51 | makeMovementFlags(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)
52 |
53 | override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
54 | target: RecyclerView.ViewHolder): Boolean = false
55 |
56 | // When an item is swiped, remove the item via the view model. The list item will be
57 | // automatically removed in response, because the adapter is observing the live list.
58 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
59 | (viewHolder as? CheeseViewHolder)?.cheese?.let {
60 | viewModel.remove(it)
61 | }
62 | }
63 | }).attachToRecyclerView(cheeseList)
64 | }
65 |
66 | private fun addCheese() {
67 | val newCheese = inputText.text.trim()
68 | if (newCheese.isNotEmpty()) {
69 | viewModel.insert(newCheese)
70 | inputText.setText("")
71 | }
72 | }
73 |
74 | private fun initAddButtonListener() {
75 | addButton.setOnClickListener {
76 | addCheese()
77 | }
78 |
79 | // when the user taps the "Done" button in the on screen keyboard, save the item.
80 | inputText.setOnEditorActionListener({ _, actionId, _ ->
81 | if (actionId == EditorInfo.IME_ACTION_DONE) {
82 | addCheese()
83 | return@setOnEditorActionListener true
84 | }
85 | false // action that isn't DONE occurred - ignore
86 | })
87 | // When the user clicks on the button, or presses enter, save the item.
88 | inputText.setOnKeyListener({ _, keyCode, event ->
89 | if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
90 | addCheese()
91 | return@setOnKeyListener true
92 | }
93 | false // event that isn't DOWN or ENTER occurred - ignore
94 | })
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/lilingzhi/llvr/WorkManagerActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.lilingzhi.llvr;
2 |
3 | import android.arch.lifecycle.Observer;
4 | import android.provider.SyncStateContract;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.Button;
10 |
11 | import com.example.lilingzhi.llvr.workmanager.TestWorker;
12 |
13 | import java.util.UUID;
14 | import java.util.concurrent.TimeUnit;
15 |
16 | import androidx.work.Constraints;
17 | import androidx.work.OneTimeWorkRequest;
18 | import androidx.work.PeriodicWorkRequest;
19 | import androidx.work.WorkManager;
20 | import androidx.work.WorkStatus;
21 |
22 | public class WorkManagerActivity extends AppCompatActivity {
23 |
24 |
25 | Button btn_one,btn_constraint,btn_cancel,btn_period;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_work_manager);
31 |
32 | btn_one=(Button)findViewById(R.id.btn_one);
33 | btn_one.setOnClickListener(new View.OnClickListener() {
34 | @Override
35 | public void onClick(View v) {
36 | //只执行一次,如果worker返回 FAILURE,将会再执行几次,这个几次不固定,
37 | //其他情况只执行一次,worker不能返回空
38 | OneTimeWorkRequest oneTimeWorkRequest=new OneTimeWorkRequest.Builder(TestWorker.class).build();
39 | WorkManager.getInstance().enqueue(oneTimeWorkRequest);
40 |
41 | //监听任务执行情况
42 | WorkManager.getInstance().getStatusById(oneTimeWorkRequest.getId())
43 | .observe(WorkManagerActivity.this, new Observer> data=new MutableLiveData<>();
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_room);
36 |
37 | btn_insert=(Button)findViewById(R.id.btn_insert);
38 | btn_update=(Button)findViewById(R.id.btn_update);
39 | btn_delete=(Button)findViewById(R.id.btn_delete);
40 | btn_get=(Button)findViewById(R.id.btn_get);
41 | tv=(TextView)findViewById(R.id.tv);
42 |
43 | getSupportActionBar().setTitle("Room");
44 |
45 |
46 | dataBase=Room.databaseBuilder(getApplicationContext(), TestDataBase.class,"test")
47 | .addCallback(new RoomDatabase.Callback() {
48 | @Override
49 | public void onCreate(@NonNull SupportSQLiteDatabase db) {
50 | super.onCreate(db);
51 | }
52 |
53 | @Override
54 | public void onOpen(@NonNull SupportSQLiteDatabase db) {
55 | super.onOpen(db);
56 | }
57 | })
58 | .allowMainThreadQueries()//允许在主线程查询数据
59 | .addMigrations()//迁移数据库使用
60 | .fallbackToDestructiveMigration()//迁移数据库如果发生错误,将会重新创建数据库,而不是发生崩溃
61 | .build();
62 | testDao=dataBase.testDao();
63 |
64 | data.observe(this, new Observer
>() {
65 | @Override
66 | public void onChanged(@Nullable List