Adds top level navigation and placeholder fragments.
This commit is contained in:
		| @@ -31,7 +31,10 @@ public class MainActivity extends AppCompatActivity { | ||||
|         // Passing each menu ID as a set of Ids because each | ||||
|         // menu should be considered as top level destinations. | ||||
|         AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( | ||||
|                 R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications) | ||||
|                 R.id.navigation_search, | ||||
|                 R.id.navigation_dashboard, | ||||
|                 R.id.navigation_collections, | ||||
|                 R.id.navigation_library) | ||||
|                 .build(); | ||||
|         NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); | ||||
|         NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); | ||||
|   | ||||
| @@ -7,21 +7,29 @@ import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.Observer; | ||||
| import androidx.lifecycle.ViewModelProviders; | ||||
|  | ||||
| import com.majinnaibu.monstercards.R; | ||||
| import com.majinnaibu.monstercards.ui.shared.MCFragment; | ||||
|  | ||||
| public class CollectionsFragment extends MCFragment { | ||||
| public class CollectionsFragment extends Fragment { | ||||
|  | ||||
|     private CollectionsViewModel collectionsViewModel; | ||||
|  | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, | ||||
|                              ViewGroup container, Bundle savedInstanceState) { | ||||
|         collectionsViewModel = new ViewModelProvider(this).get(CollectionsViewModel.class); | ||||
|         collectionsViewModel = | ||||
|                 ViewModelProviders.of(this).get(CollectionsViewModel.class); | ||||
|         View root = inflater.inflate(R.layout.fragment_collections, container, false); | ||||
|         final TextView textView = root.findViewById(R.id.text_collections); | ||||
|         collectionsViewModel.getText().observe(getViewLifecycleOwner(), textView::setText); | ||||
|         collectionsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { | ||||
|             @Override | ||||
|             public void onChanged(@Nullable String s) { | ||||
|                 textView.setText(s); | ||||
|             } | ||||
|         }); | ||||
|         return root; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel; | ||||
|  | ||||
| public class CollectionsViewModel extends ViewModel { | ||||
|  | ||||
|     private final MutableLiveData<String> mText; | ||||
|     private MutableLiveData<String> mText; | ||||
|  | ||||
|     public CollectionsViewModel() { | ||||
|         mText = new MutableLiveData<>(); | ||||
|   | ||||
| @@ -1,35 +0,0 @@ | ||||
| package com.majinnaibu.monstercards.ui.home; | ||||
|  | ||||
| import android.os.Bundle; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.Observer; | ||||
| import androidx.lifecycle.ViewModelProviders; | ||||
|  | ||||
| import com.majinnaibu.monstercards.R; | ||||
|  | ||||
| public class HomeFragment extends Fragment { | ||||
|  | ||||
|     private HomeViewModel homeViewModel; | ||||
|  | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, | ||||
|                              ViewGroup container, Bundle savedInstanceState) { | ||||
|         homeViewModel = | ||||
|                 ViewModelProviders.of(this).get(HomeViewModel.class); | ||||
|         View root = inflater.inflate(R.layout.fragment_home, container, false); | ||||
|         final TextView textView = root.findViewById(R.id.text_home); | ||||
|         homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { | ||||
|             @Override | ||||
|             public void onChanged(@Nullable String s) { | ||||
|                 textView.setText(s); | ||||
|             } | ||||
|         }); | ||||
|         return root; | ||||
|     } | ||||
| } | ||||
| @@ -1,121 +1,35 @@ | ||||
| package com.majinnaibu.monstercards.ui.library; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.os.Bundle; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.navigation.NavDirections; | ||||
| import androidx.navigation.Navigation; | ||||
| import androidx.recyclerview.widget.DividerItemDecoration; | ||||
| import androidx.recyclerview.widget.ItemTouchHelper; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.Observer; | ||||
| import androidx.lifecycle.ViewModelProviders; | ||||
|  | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton; | ||||
| import com.google.android.material.snackbar.Snackbar; | ||||
| import com.majinnaibu.monstercards.R; | ||||
| import com.majinnaibu.monstercards.data.MonsterRepository; | ||||
| import com.majinnaibu.monstercards.models.Monster; | ||||
| import com.majinnaibu.monstercards.ui.shared.MCFragment; | ||||
| import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback; | ||||
| import com.majinnaibu.monstercards.utils.Logger; | ||||
|  | ||||
| import java.util.UUID; | ||||
| public class LibraryFragment extends Fragment { | ||||
|  | ||||
| import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; | ||||
| import io.reactivex.rxjava3.observers.DisposableCompletableObserver; | ||||
| import io.reactivex.rxjava3.schedulers.Schedulers; | ||||
|  | ||||
| public class LibraryFragment extends MCFragment { | ||||
|     private LibraryViewModel libraryViewModel; | ||||
|  | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, | ||||
|                              ViewGroup container, Bundle savedInstanceState) { | ||||
|         libraryViewModel = | ||||
|                 ViewModelProviders.of(this).get(LibraryViewModel.class); | ||||
|         View root = inflater.inflate(R.layout.fragment_library, container, false); | ||||
|  | ||||
|         FloatingActionButton fab = root.findViewById(R.id.fab); | ||||
|         assert fab != null; | ||||
|         setupAddMonsterButton(fab); | ||||
|  | ||||
|         final RecyclerView recyclerView = root.findViewById(R.id.monster_list); | ||||
|         assert recyclerView != null; | ||||
|         setupRecyclerView(recyclerView); | ||||
|  | ||||
|         final TextView textView = root.findViewById(R.id.text_library); | ||||
|         libraryViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { | ||||
|             @Override | ||||
|             public void onChanged(@Nullable String s) { | ||||
|                 textView.setText(s); | ||||
|             } | ||||
|         }); | ||||
|         return root; | ||||
|     } | ||||
|  | ||||
|     private void setupRecyclerView(@NonNull RecyclerView recyclerView) { | ||||
|         Context context = requireContext(); | ||||
|         MonsterRepository repository = this.getMonsterRepository(); | ||||
|  | ||||
|         LibraryRecyclerViewAdapter adapter = new LibraryRecyclerViewAdapter( | ||||
|                 context, | ||||
|                 repository.getMonsters(), | ||||
|                 (monster) -> navigateToMonsterDetail(monster.id), | ||||
|                 (monster) -> repository | ||||
|                         .deleteMonster(monster) | ||||
|                         .subscribeOn(Schedulers.io()) | ||||
|                         .observeOn(AndroidSchedulers.mainThread()) | ||||
|                         .subscribe(new DisposableCompletableObserver() { | ||||
|                             @Override | ||||
|                             public void onComplete() { | ||||
|                             } | ||||
|  | ||||
|                             @Override | ||||
|                             public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { | ||||
|                                 Logger.logError(e); | ||||
|                             } | ||||
|                         })); | ||||
|         recyclerView.setAdapter(adapter); | ||||
|  | ||||
|         LinearLayoutManager layoutManager = new LinearLayoutManager(context); | ||||
|         recyclerView.setLayoutManager(layoutManager); | ||||
|  | ||||
|         DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, layoutManager.getOrientation()); | ||||
|         recyclerView.addItemDecoration(dividerItemDecoration); | ||||
|  | ||||
|         ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(requireContext(), (position, direction) -> adapter.deleteItem(position), null)); | ||||
|         itemTouchHelper.attachToRecyclerView(recyclerView); | ||||
|     } | ||||
|  | ||||
|     private void setupAddMonsterButton(@NonNull FloatingActionButton fab) { | ||||
|         fab.setOnClickListener(view -> { | ||||
|             Monster monster = new Monster(); | ||||
|             monster.name = getString(R.string.default_monster_name); | ||||
|             MonsterRepository repository = this.getMonsterRepository(); | ||||
|             repository.addMonster(monster) | ||||
|                     .subscribeOn(Schedulers.io()) | ||||
|                     .observeOn(AndroidSchedulers.mainThread()) | ||||
|                     .subscribe( | ||||
|                             new DisposableCompletableObserver() { | ||||
|                                 @Override | ||||
|                                 public void onComplete() { | ||||
|                                     View view = getView(); | ||||
|                                     assert view != null; | ||||
|                                     Snackbar.make( | ||||
|                                             view, | ||||
|                                             getString(R.string.snackbar_monster_created, monster.name), | ||||
|                                             Snackbar.LENGTH_LONG) | ||||
|                                             .setAction("Action", (_view) -> navigateToMonsterDetail(monster.id)) | ||||
|                                             .show(); | ||||
|                                 } | ||||
|  | ||||
|                                 @Override | ||||
|                                 public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) { | ||||
|                                     Logger.logError("Error creating monster", e); | ||||
|                                     View view = getView(); | ||||
|                                     assert view != null; | ||||
|                                     Snackbar.make(view, getString(R.string.snackbar_failed_to_create_monster), Snackbar.LENGTH_LONG) | ||||
|                                             .setAction("Action", null).show(); | ||||
|                                 } | ||||
|                             }); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     protected void navigateToMonsterDetail(@NonNull UUID monsterId) { | ||||
|         NavDirections action = LibraryFragmentDirections.actionNavigationLibraryToNavigationMonster(monsterId.toString()); | ||||
|         Navigation.findNavController(requireView()).navigate(action); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,19 +1,19 @@ | ||||
| package com.majinnaibu.monstercards.ui.notifications; | ||||
| package com.majinnaibu.monstercards.ui.library; | ||||
| 
 | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.lifecycle.ViewModel; | ||||
| 
 | ||||
| public class NotificationsViewModel extends ViewModel { | ||||
| public class LibraryViewModel extends ViewModel { | ||||
| 
 | ||||
|     private MutableLiveData<String> mText; | ||||
| 
 | ||||
|     public NotificationsViewModel() { | ||||
|     public LibraryViewModel() { | ||||
|         mText = new MutableLiveData<>(); | ||||
|         mText.setValue("This is notifications fragment"); | ||||
|         mText.setValue("This is library fragment"); | ||||
|     } | ||||
| 
 | ||||
|     public LiveData<String> getText() { | ||||
|         return mText; | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -1,35 +0,0 @@ | ||||
| package com.majinnaibu.monstercards.ui.notifications; | ||||
|  | ||||
| import android.os.Bundle; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.Observer; | ||||
| import androidx.lifecycle.ViewModelProviders; | ||||
|  | ||||
| import com.majinnaibu.monstercards.R; | ||||
|  | ||||
| public class NotificationsFragment extends Fragment { | ||||
|  | ||||
|     private NotificationsViewModel notificationsViewModel; | ||||
|  | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, | ||||
|                              ViewGroup container, Bundle savedInstanceState) { | ||||
|         notificationsViewModel = | ||||
|                 ViewModelProviders.of(this).get(NotificationsViewModel.class); | ||||
|         View root = inflater.inflate(R.layout.fragment_notifications, container, false); | ||||
|         final TextView textView = root.findViewById(R.id.text_notifications); | ||||
|         notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { | ||||
|             @Override | ||||
|             public void onChanged(@Nullable String s) { | ||||
|                 textView.setText(s); | ||||
|             } | ||||
|         }); | ||||
|         return root; | ||||
|     } | ||||
| } | ||||
| @@ -1,53 +1,35 @@ | ||||
| package com.majinnaibu.monstercards.ui.search; | ||||
|  | ||||
| import android.os.Bundle; | ||||
| import android.text.Editable; | ||||
| import android.text.TextWatcher; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.Observer; | ||||
| import androidx.lifecycle.ViewModelProviders; | ||||
|  | ||||
| import com.majinnaibu.monstercards.R; | ||||
| import com.majinnaibu.monstercards.data.MonsterRepository; | ||||
| import com.majinnaibu.monstercards.ui.shared.MCFragment; | ||||
|  | ||||
| public class SearchFragment extends MCFragment { | ||||
| public class SearchFragment extends Fragment { | ||||
|  | ||||
|     private SearchViewModel searchViewModel; | ||||
|  | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, | ||||
|                              ViewGroup container, Bundle savedInstanceState) { | ||||
|         searchViewModel = | ||||
|                 ViewModelProviders.of(this).get(SearchViewModel.class); | ||||
|         View root = inflater.inflate(R.layout.fragment_search, container, false); | ||||
|         MonsterRepository repository = this.getMonsterRepository(); | ||||
|         SearchResultsRecyclerViewAdapter adapter = new SearchResultsRecyclerViewAdapter(repository, null); | ||||
|         final RecyclerView recyclerView = root.findViewById(R.id.monster_list); | ||||
|         assert recyclerView != null; | ||||
|         setupRecyclerView(recyclerView, adapter); | ||||
|  | ||||
|         final TextView textView = root.findViewById(R.id.search_query); | ||||
|         textView.addTextChangedListener(new TextWatcher() { | ||||
|         final TextView textView = root.findViewById(R.id.text_search); | ||||
|         searchViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { | ||||
|             @Override | ||||
|             public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void afterTextChanged(Editable editable) { | ||||
|                 adapter.doSearch(textView.getText().toString()); | ||||
|             public void onChanged(@Nullable String s) { | ||||
|                 textView.setText(s); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         return root; | ||||
|     } | ||||
|  | ||||
|     private void setupRecyclerView(@NonNull RecyclerView recyclerView, @NonNull SearchResultsRecyclerViewAdapter adapter) { | ||||
|         recyclerView.setAdapter(adapter); | ||||
|         recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,16 +1,16 @@ | ||||
| package com.majinnaibu.monstercards.ui.home; | ||||
| package com.majinnaibu.monstercards.ui.search; | ||||
| 
 | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.lifecycle.ViewModel; | ||||
| 
 | ||||
| public class HomeViewModel extends ViewModel { | ||||
| public class SearchViewModel extends ViewModel { | ||||
| 
 | ||||
|     private MutableLiveData<String> mText; | ||||
| 
 | ||||
|     public HomeViewModel() { | ||||
|     public SearchViewModel() { | ||||
|         mText = new MutableLiveData<>(); | ||||
|         mText.setValue("This is home fragment"); | ||||
|         mText.setValue("This is search fragment"); | ||||
|     } | ||||
| 
 | ||||
|     public LiveData<String> getText() { | ||||
		Reference in New Issue
	
	Block a user
	 Tom Hicks
						Tom Hicks