左耳聽風(fēng)ARTS 100天打卡計劃
(1)Algorithm 每周至少做一個 leetcode 的算法題-為了編程訓(xùn)練和學(xué)習(xí)
(2)Review 每周閱讀并點評至少一篇英文技術(shù)文章-為了學(xué)習(xí)英文,接觸一手知識點
(3)Tip 每周學(xué)習(xí)至少一個技術(shù)技巧-總結(jié)和歸納工作中遇到的知識點
(4)Share? 每周分享一篇有觀點和思考的技術(shù)文章-建立影響力,輸出價值觀
week1(3/18-3/24)
A
三數(shù)之和,復(fù)雜度為O(n2)
private static List<List<Integer>> threeSum(int[] num) {
? ? Arrays.sort(num);
? ? List<List<Integer>> res = new LinkedList<List<Integer>>();
? ? for (int i = 0; i < num.length - 2; i++) {
? ? ? ? if (i == 0 || (i > 0 && num[i] != num[i - 1])) {
? ? ? ? ? ? int lo = i + 1, hi = num.length - 1, sum = 0 - num[i];
? ? ? ? ? ? while (lo < hi) {
? ? ? ? ? ? ? ? if (num[lo] + num[hi] == sum) {
? ? ? ? ? ? ? ? ? ? res.add(Arrays.asList(num[i], num[lo], num[hi]));
? ? ? ? ? ? ? ? ? ? while (lo < hi && num[lo] == num[lo + 1]) lo++;
? ? ? ? ? ? ? ? ? ? while (lo < hi && num[hi] == num[hi - 1]) hi--;
? ? ? ? ? ? ? ? ? ? lo++;
? ? ? ? ? ? ? ? ? ? hi--;
? ? ? ? ? ? ? ? } else if (num[lo] + num[hi] < sum) lo++;
? ? ? ? ? ? ? ? else hi--;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return res;
}
R
https://developer.android.com/topic/libraries/architecture/viewmodel
viewmodel 是被設(shè)計為存儲和管理UI重建時候的數(shù)據(jù),以一種可以感知生命周期的方式. 它允許在配置發(fā)生改變時候(例如屏幕旋轉(zhuǎn))繼續(xù)存在,android framework 管理UI控制器的生命周期,例如activity 和 fragments. 在系統(tǒng)重建UI 控制器的時候存儲的數(shù)據(jù)會丟失,可以使用onSaveInstanceState() 方法來存儲和恢復(fù)數(shù)據(jù)通過bundle 在onCreate()方法里面. 但是這種方式僅僅適用于可以序列化和反序列化的少量數(shù)據(jù),并不使用與大量的數(shù)據(jù),比如說用戶列表和bitmaps.
另外一個問題是UI 控制器需要頻繁的進行異步請求,這需要花費一些時間來返回. UI 控制器需要去管理這些請求,確保在的destory的時候可以clean 他們以避免潛在的內(nèi)存泄露.這種管理需要重建一些對象,浪費一些資源
UI控制器主要的職責(zé)是呈現(xiàn)UI數(shù)據(jù),響應(yīng)用戶的action或者是系統(tǒng)的交互,過多的邏輯在里面會導(dǎo)致該類增多,將數(shù)據(jù)的數(shù)據(jù)分離出來對于view來說
更加高效.
public class MyViewModel extends ViewModel {
? ? private MutableLiveData<List<User>> users;
? ? public LiveData<List<User>> getUsers() {
? ? ? ? if (users == null) {
? ? ? ? ? ? users = new MutableLiveData<List<User>>();
? ? ? ? ? ? loadUsers();
? ? ? ? }
? ? ? ? return users;
? ? }
? ? private void loadUsers() {
? ? ? ? // Do an asynchronous operation to fetch users.
? ? }
}
public class MyActivity extends AppCompatActivity {
? ? public void onCreate(Bundle savedInstanceState) {
? ? ? ? // Create a ViewModel the first time the system calls an activity's onCreate() method.
? ? ? ? // Re-created activities receive the same MyViewModel instance created by the first activity.
? ? ? ? MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
? ? ? ? model.getUsers().observe(this, users -> {
? ? ? ? ? ? // update UI
? ? ? ? });
? ? }
}
當activity重建的時候 viewmodel 所使用的實例是第一次activity創(chuàng)建的時候的實例.當它銷毀的時候,系統(tǒng)會調(diào)用onCleared()方法去清空資源.
ViewModel絕不能引用視圖耸棒,生命周期或任何可能包含對活動上下文的引用的類雕旨。
生命周期如下圖:
public class SharedViewModel extends ViewModel {
? ? private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
? ? public void select(Item item) {
? ? ? ? selected.setValue(item);
? ? }
? ? public LiveData<Item> getSelected() {
? ? ? ? return selected;
? ? }
}
public class MasterFragment extends Fragment {
? ? private SharedViewModel model;
? ? public void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
? ? ? ? itemSelector.setOnClickListener(item -> {
? ? ? ? ? ? model.select(item);
? ? ? ? });
? ? }
}
public class DetailFragment extends Fragment {
? ? public void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
? ? ? ? model.getSelected().observe(this, { item ->
? ? ? ? ? ?// Update the UI.
? ? ? ? });
? ? }
}
T
android 里面的拖拽的使用
oneView.startDrag(data, new View.DragShadowBuilder(view), view, 0);
使用startDarg來開啟當前view的拖拽,其他所有view都會收到這個view拖拽的通知
其他view的處理
public class TwoView extends View {
? ? public static final String TAG = "dragview";
? ? public TwoView(Context context, @Nullable AttributeSet attrs) {
? ? ? ? super(context, attrs);
? ? }
? ? @Override
? ? public boolean onDragEvent(DragEvent event) {
? ? ? ? boolean result = false;
? ? ? ? switch (event.getAction()) {
? ? ? ? ? ? case DragEvent.ACTION_DRAG_STARTED:
? ? ? ? ? ? ? ? result = true;
? ? ? ? ? ? ? ? Log.d(TAG, " 有view 開始拖拽");
? ? ? ? ? ? ? ? View dragView = (View) event.getLocalState();
? ? ? ? ? ? ? ? dragView.setVisibility(INVISIBLE);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case DragEvent.ACTION_DRAG_LOCATION:
? ? ? ? ? ? ? ? Log.i(TAG, "被拖動的View進入當前View后染苛,位置發(fā)生改變!");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case DragEvent.ACTION_DROP:
? ? ? ? ? ? ? ? Log.i(TAG, "拖動的View被放入當前View!");
? ? ? ? ? ? ? ? /**
? ? ? ? ? ? ? ? * 在放時交互兩個View的背景。
? ? ? ? ? ? ? ? */
? ? ? ? ? ? ? ? View mDragView = (View) event.getLocalState();
? ? ? ? ? ? ? ? Drawable mDragViewBackgroud = mDragView.getBackground();
? ? ? ? ? ? ? ? mDragView.setBackgroundDrawable(this.getBackground());
? ? ? ? ? ? ? ? this.setBackgroundDrawable(mDragViewBackgroud);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case DragEvent.ACTION_DRAG_ENDED: {
? ? ? ? ? ? ? ? View dragView1 = (View) event.getLocalState();
? ? ? ? ? ? ? ? dragView1.setVisibility(VISIBLE);
? ? ? ? ? ? ? ? Log.i(TAG, "拖動結(jié)束!");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? case DragEvent.ACTION_DRAG_EXITED: {
? ? ? ? ? ? ? ? Log.i(TAG, "拖動退出!");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? default: {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return result;
? ? }
代碼https://github.com/onebee/milestone/tree/master/dragsample
https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e