StateMaintainer, ItemDetailFragment were added + minor architecture changes
This commit is contained in:
parent
c6bfad37f0
commit
f95b8d11b7
|
@ -28,15 +28,15 @@ dependencies {
|
|||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
|
||||
compile 'com.android.support:support-v4:23.3.0'
|
||||
compile 'com.google.code.gson:gson:2.6.2'
|
||||
compile 'com.squareup.retrofit2:retrofit:2.0.1'
|
||||
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
|
||||
compile 'com.squareup.okhttp3:okhttp:3.2.0'
|
||||
|
||||
compile 'com.squareup.okhttp:logging-interceptor:2.7.0'
|
||||
compile 'com.android.support:support-v4:23.3.0'
|
||||
compile 'com.android.support:appcompat-v7:23.3.0'
|
||||
compile 'com.android.support:design:23.3.0'
|
||||
compile 'com.android.support:support-v4:23.3.0'
|
||||
compile 'com.android.support:cardview-v7:23.3.0'
|
||||
}
|
||||
|
|
|
@ -5,44 +5,182 @@ import android.app.Fragment;
|
|||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import hikapro.com.backpack.model.DetailModel;
|
||||
import hikapro.com.backpack.model.ItemModel;
|
||||
import hikapro.com.backpack.model.SetModel;
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.model.entities.Set;
|
||||
import hikapro.com.backpack.presenter.ItemDetailPresenter;
|
||||
import hikapro.com.backpack.presenter.ItemListPresenter;
|
||||
import hikapro.com.backpack.presenter.SetListPresenter;
|
||||
import hikapro.com.backpack.view.View;
|
||||
import hikapro.com.backpack.view.fragments.ItemDetailFragment;
|
||||
import hikapro.com.backpack.view.fragments.ItemListFragment;
|
||||
import hikapro.com.backpack.view.fragments.SetListFragment;
|
||||
|
||||
public class MainActivity extends Activity implements View.ActivityCallback {
|
||||
|
||||
private static String TAG = "TAG";
|
||||
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
private final StateMaintainer stateMaintainer =
|
||||
new StateMaintainer(getFragmentManager(), MainActivity.class.getName());
|
||||
|
||||
// life cycle -->
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
fragmentManager = getFragmentManager();
|
||||
|
||||
Fragment fragment = fragmentManager.findFragmentByTag(TAG);
|
||||
if (fragment == null)
|
||||
replaceFragment(SetListFragment.construct(), false);
|
||||
stateMaintainer.init();
|
||||
|
||||
if (fragmentManager.getBackStackEntryCount() == 0) {
|
||||
startSetListFragment();
|
||||
} else {
|
||||
|
||||
Fragment fragment = fragmentManager.findFragmentByTag(SetListFragment.class.getName());
|
||||
if (fragment != null) {
|
||||
SetListFragment view = (SetListFragment) fragment;
|
||||
SetListPresenter presenter = stateMaintainer.get(SetListPresenter.class.getName());
|
||||
SetModel model = stateMaintainer.get(SetModel.class.getName());
|
||||
|
||||
view.setPresenter(presenter);
|
||||
presenter.setView(view);
|
||||
presenter.setModel(model);
|
||||
model.setPresenter(presenter);
|
||||
|
||||
}
|
||||
|
||||
fragment = fragmentManager.findFragmentByTag(ItemListFragment.class.getName());
|
||||
if (fragment != null) {
|
||||
ItemListFragment view = (ItemListFragment) fragment;
|
||||
ItemListPresenter presenter = stateMaintainer.get(ItemListPresenter.class.getName());
|
||||
ItemModel model = stateMaintainer.get(ItemModel.class.getName());
|
||||
|
||||
view.setPresenter(presenter);
|
||||
presenter.setView(view);
|
||||
presenter.setModel(model);
|
||||
model.setPresenter(presenter);
|
||||
|
||||
}
|
||||
|
||||
fragment = fragmentManager.findFragmentByTag(ItemDetailFragment.class.getName());
|
||||
if (fragment != null) {
|
||||
ItemDetailFragment view = (ItemDetailFragment) fragment;
|
||||
ItemDetailPresenter presenter = stateMaintainer.get(ItemDetailPresenter.class.getName());
|
||||
DetailModel model = stateMaintainer.get(DetailModel.class.getName());
|
||||
|
||||
view.setPresenter(presenter);
|
||||
presenter.setView(view);
|
||||
presenter.setModel(model);
|
||||
model.setPresenter(presenter);
|
||||
}
|
||||
}
|
||||
Log.i("On create", "Activity");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
Log.i("onStart", "Activity");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
Log.i("onRestart", "Activity");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
Log.i("onResume", "Activity");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
Log.i("onPause", "Activity");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
Log.i("onStop", "Activity");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.i("onDestroy", "Activity");
|
||||
}
|
||||
// life cycle <--
|
||||
|
||||
|
||||
@Override
|
||||
public void startSetListFragment() {
|
||||
|
||||
SetListFragment view = SetListFragment.construct();
|
||||
SetListPresenter presenter = new SetListPresenter();
|
||||
SetModel model = new SetModel();
|
||||
|
||||
view.setPresenter(presenter);
|
||||
presenter.setView(view);
|
||||
presenter.setModel(model);
|
||||
model.setPresenter(presenter);
|
||||
|
||||
replaceFragment(view, true, SetListFragment.class.getName());
|
||||
|
||||
stateMaintainer.put(presenter);
|
||||
stateMaintainer.put(model);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startItemListFragment(Set set) {
|
||||
replaceFragment(ItemListFragment.newFromSet(set), true);
|
||||
|
||||
ItemListFragment view = ItemListFragment.newFromSet(set);
|
||||
ItemListPresenter presenter = new ItemListPresenter();
|
||||
ItemModel model = new ItemModel();
|
||||
|
||||
view.setPresenter(presenter);
|
||||
presenter.setView(view);
|
||||
presenter.setModel(model);
|
||||
model.setPresenter(presenter);
|
||||
|
||||
replaceFragment(view, true, ItemListFragment.class.getName());
|
||||
|
||||
stateMaintainer.put(presenter);
|
||||
stateMaintainer.put(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startItemDetailFragment() {
|
||||
public void startItemDetailFragment(Item item) {
|
||||
|
||||
ItemDetailFragment view = ItemDetailFragment.newFromItem(item);
|
||||
ItemDetailPresenter presenter = new ItemDetailPresenter();
|
||||
DetailModel model = new DetailModel();
|
||||
|
||||
view.setPresenter(presenter);
|
||||
presenter.setView(view);
|
||||
presenter.setModel(model);
|
||||
model.setPresenter(presenter);
|
||||
|
||||
replaceFragment(view, true, ItemDetailFragment.class.getName());
|
||||
|
||||
stateMaintainer.put(presenter);
|
||||
stateMaintainer.put(model);
|
||||
}
|
||||
|
||||
private void replaceFragment(Fragment fragment, boolean addBackStack) {
|
||||
private void replaceFragment(Fragment fragment, boolean addBackStack, String tag) {
|
||||
FragmentTransaction transaction = fragmentManager.beginTransaction();
|
||||
transaction.replace(R.id.container, fragment, TAG);
|
||||
transaction.replace(R.id.container, fragment, tag);
|
||||
if (addBackStack)
|
||||
transaction.addToBackStack(null);
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package hikapro.com.backpack;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by tariel on 24/04/16.
|
||||
*/
|
||||
public class StateMaintainer {
|
||||
|
||||
protected final String TAG = getClass().getSimpleName();
|
||||
private final String stateMaintainerTag;
|
||||
private final WeakReference<FragmentManager> fragmentManager;
|
||||
private StateMngFragment stateMngFragment;
|
||||
private boolean isRecreating;
|
||||
|
||||
|
||||
public StateMaintainer(FragmentManager fragmentManager, String stateMaintainerTAG) {
|
||||
this.fragmentManager = new WeakReference<>(fragmentManager);
|
||||
this.stateMaintainerTag = stateMaintainerTAG;
|
||||
}
|
||||
|
||||
public boolean init() {
|
||||
try {
|
||||
stateMngFragment = (StateMngFragment)
|
||||
fragmentManager.get().findFragmentByTag(stateMaintainerTag);
|
||||
|
||||
if (stateMngFragment == null) {
|
||||
stateMngFragment = new StateMngFragment();
|
||||
fragmentManager.get().beginTransaction()
|
||||
.add(stateMngFragment, stateMaintainerTag).commit();
|
||||
isRecreating = false;
|
||||
return true;
|
||||
} else {
|
||||
isRecreating = true;
|
||||
return false;
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean wasRecreated() { return isRecreating; }
|
||||
|
||||
public void put(String key, Object obj) {
|
||||
stateMngFragment.put(key, obj);
|
||||
}
|
||||
|
||||
public void put(Object obj) {
|
||||
put(obj.getClass().getName(), obj);
|
||||
}
|
||||
|
||||
public <T> T get(String key) {
|
||||
return stateMngFragment.get(key);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasKey(String key) {
|
||||
return stateMngFragment.get(key) != null;
|
||||
}
|
||||
|
||||
|
||||
public static class StateMngFragment extends Fragment {
|
||||
|
||||
private HashMap<String, Object> data = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// Grants that the fragment will be preserved
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
|
||||
public void put(String key, Object obj) {
|
||||
data.put(key, obj);
|
||||
Log.i(this.toString(), String.format("Put object %s Total count %d", key, data.size()));
|
||||
}
|
||||
|
||||
|
||||
public void put(Object object) {
|
||||
put(object.getClass().getName(), object);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(String key) {
|
||||
Log.i(this.toString(), String.format("Get object %s Total count %d", key, data.size()));
|
||||
return (T) data.get(key);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package hikapro.com.backpack.model;
|
||||
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.presenter.Presenter;
|
||||
|
||||
/**
|
||||
* Created by tariel on 23/04/16.
|
||||
*/
|
||||
public class DetailModel implements Model.Detail {
|
||||
|
||||
private Presenter.ItemDetail presenter;
|
||||
private Item item;
|
||||
|
||||
public DetailModel() {
|
||||
|
||||
}
|
||||
|
||||
// detail -->
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public Item findItem(int id) {
|
||||
return item;
|
||||
}
|
||||
|
||||
// detail <--
|
||||
|
||||
// events -->
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
presenter.notifyDataSetChanged();
|
||||
}
|
||||
@Override
|
||||
public void onDestroy(boolean isConfigurationChanging) {
|
||||
if ( !isConfigurationChanging ) {
|
||||
presenter = null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
presenter.showMessage(message);
|
||||
}
|
||||
|
||||
// events <--
|
||||
|
||||
// process -->
|
||||
@Override
|
||||
public void executeQuery() {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
// process <--
|
||||
|
||||
|
||||
@Override
|
||||
public void setPresenter(Presenter.ItemDetail presenter) {
|
||||
this.presenter = presenter;
|
||||
this.item = presenter.getCurrentItem();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presenter.ItemDetail getPresenter() {
|
||||
return presenter;
|
||||
}
|
||||
}
|
|
@ -27,9 +27,8 @@ public class ItemModel implements Model.Item {
|
|||
|
||||
private Hashtable<Category, List<Item>> items;
|
||||
|
||||
public ItemModel(Presenter.ItemList presenter) {
|
||||
public ItemModel() {
|
||||
this.api = RestClient.getApi();
|
||||
this.presenter = presenter;
|
||||
this.rawCategories = new ArrayList<>();
|
||||
this.rawItems = new ArrayList<>();
|
||||
this.sortedCategories = new ArrayList<>();
|
||||
|
@ -59,8 +58,15 @@ public class ItemModel implements Model.Item {
|
|||
return false;
|
||||
}
|
||||
@Override
|
||||
public Item findItem(int id) { // TODO rename to find
|
||||
return null;
|
||||
public Item findItem(int id) {
|
||||
Item item = null;
|
||||
for (Item i : rawItems) {
|
||||
if (i.getId() == id) {
|
||||
item = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@Override
|
||||
public Item getItemByPosition(int categoryId, int position) {
|
||||
|
@ -91,7 +97,9 @@ public class ItemModel implements Model.Item {
|
|||
|
||||
@Override
|
||||
public void onDestroy(boolean isConfigurationChanging) {
|
||||
|
||||
if ( !isConfigurationChanging ) {
|
||||
presenter = null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
|
@ -103,8 +111,13 @@ public class ItemModel implements Model.Item {
|
|||
|
||||
@Override
|
||||
public void executeQuery() {
|
||||
loadCategories();
|
||||
loadItems();
|
||||
if (rawCategories.isEmpty() || rawItems.isEmpty()) {
|
||||
loadCategories();
|
||||
loadItems();
|
||||
} else {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
private void loadCategories() {
|
||||
Call<List<Category>> call = api.getItemCategories();
|
||||
|
@ -142,6 +155,17 @@ public class ItemModel implements Model.Item {
|
|||
|
||||
// other -->
|
||||
|
||||
|
||||
@Override
|
||||
public void setPresenter(Presenter.ItemList presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presenter.ItemList getPresenter() {
|
||||
return presenter;
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
List<Integer> ids = presenter.getCurrentSet().getItems();
|
||||
List<Item> sortedItems = new ArrayList<>(ids.size());
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
import hikapro.com.backpack.model.entities.Category;
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.model.entities.Set;
|
||||
import hikapro.com.backpack.presenter.Presenter;
|
||||
|
||||
/**
|
||||
* Created by tariel on 19/04/16.
|
||||
|
@ -22,6 +23,8 @@ public interface Model {
|
|||
hikapro.com.backpack.model.entities.Set findSet(int id);
|
||||
int getSetsCount();
|
||||
void notifyDataSetChanged();
|
||||
void setPresenter(Presenter.SetList presenter);
|
||||
Presenter.SetList getPresenter();
|
||||
}
|
||||
|
||||
interface Item extends Base {
|
||||
|
@ -33,6 +36,16 @@ public interface Model {
|
|||
hikapro.com.backpack.model.entities.Category getCategoryByPosition(int position);
|
||||
int getCategoriesCount();
|
||||
void notifyDataSetChanged();
|
||||
void setPresenter(Presenter.ItemList presenter);
|
||||
Presenter.ItemList getPresenter();
|
||||
}
|
||||
interface Detail extends Base {
|
||||
int getCount();
|
||||
hikapro.com.backpack.model.entities.Item findItem(int id);
|
||||
void notifyDataSetChanged();
|
||||
void setPresenter(Presenter.ItemDetail presenter);
|
||||
Presenter.ItemDetail getPresenter();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,10 +18,9 @@ public class SetModel implements Model.Set {
|
|||
private Api api;
|
||||
private Presenter.SetList presenter;
|
||||
|
||||
public SetModel(Presenter.SetList presenter) {
|
||||
public SetModel() {
|
||||
this.api = RestClient.getApi();
|
||||
this.iList = new ArrayList<>();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
// sets -->
|
||||
|
@ -53,6 +52,9 @@ public class SetModel implements Model.Set {
|
|||
|
||||
@Override
|
||||
public void onDestroy(boolean isConfigurationChanging) {
|
||||
if ( !isConfigurationChanging ) {
|
||||
presenter = null;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
|
@ -71,6 +73,13 @@ public class SetModel implements Model.Set {
|
|||
|
||||
@Override
|
||||
public void executeQuery() {
|
||||
if (iList.isEmpty())
|
||||
loadSets();
|
||||
else
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void loadSets() {
|
||||
Call<List<hikapro.com.backpack.model.entities.Set>> call = api.getSets();
|
||||
call.enqueue(new Callback<List<hikapro.com.backpack.model.entities.Set>>() {
|
||||
@Override
|
||||
|
@ -91,6 +100,17 @@ public class SetModel implements Model.Set {
|
|||
// process <--
|
||||
|
||||
// other -->
|
||||
|
||||
@Override
|
||||
public void setPresenter(Presenter.SetList presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presenter.SetList getPresenter() {
|
||||
return presenter;
|
||||
}
|
||||
|
||||
// other <--
|
||||
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@ package hikapro.com.backpack.model.entities;
|
|||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by tariel on 02/04/16.
|
||||
*/
|
||||
public class Item implements Comparable<Item> {
|
||||
public class Item implements Comparable<Item>, Serializable {
|
||||
|
||||
@SerializedName("id")
|
||||
@Expose
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package hikapro.com.backpack.presenter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import hikapro.com.backpack.R;
|
||||
import hikapro.com.backpack.model.Model;
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.presenter.adapters.ItemDetailAdapter;
|
||||
import hikapro.com.backpack.view.View;
|
||||
import hikapro.com.backpack.view.recycler.DetailViewHolder;
|
||||
|
||||
/**
|
||||
* Created by tariel on 23/04/16.
|
||||
*/
|
||||
public class ItemDetailPresenter implements Presenter.ItemDetail {
|
||||
|
||||
private WeakReference<View.ItemDetail> view;
|
||||
private Model.Detail model;
|
||||
private ItemDetailAdapter adapter;
|
||||
private Item item;
|
||||
|
||||
public ItemDetailPresenter() {
|
||||
this.adapter = new ItemDetailAdapter(this);
|
||||
}
|
||||
|
||||
// life cycle -->
|
||||
|
||||
@Override
|
||||
public void onDestroy(boolean isChangingConfiguration) {
|
||||
view = null;
|
||||
model.onDestroy(isChangingConfiguration);
|
||||
if ( !isChangingConfiguration ) {
|
||||
model = null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
android.view.View view = inflater.inflate(R.layout.fragment_item_detail, container, false);
|
||||
LinearLayoutManager llm = new LinearLayoutManager(getActivityContext());
|
||||
RecyclerView detailRecycler = (RecyclerView) view.findViewById(R.id.item_detail_recycler);
|
||||
detailRecycler.setLayoutManager(llm);
|
||||
detailRecycler.setAdapter(adapter);
|
||||
detailRecycler.setItemAnimator(new DefaultItemAnimator());
|
||||
model.executeQuery();
|
||||
return view;
|
||||
}
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
|
||||
}
|
||||
// life cycle <--
|
||||
|
||||
// recycler -->
|
||||
|
||||
@Override
|
||||
public int getItemsCount() {
|
||||
return model.getCount();
|
||||
}
|
||||
@Override
|
||||
public void bindViewHolder(DetailViewHolder holder, int position) {
|
||||
hikapro.com.backpack.model.entities.Item item = model.findItem(position);
|
||||
holder.title.setText(item.getName());
|
||||
holder.description.setText(item.getDescription());
|
||||
holder.title.setOnClickListener(new android.view.View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(android.view.View view) {
|
||||
showMessage("On detail click");
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public DetailViewHolder createViewHolder(ViewGroup parent, int viewType) {
|
||||
DetailViewHolder viewHolder;
|
||||
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail,
|
||||
parent, false);
|
||||
viewHolder = new DetailViewHolder(v);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
// recycler <--
|
||||
|
||||
// process -->
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// process <--
|
||||
|
||||
// other impl -->
|
||||
|
||||
@Override
|
||||
public void setView(View.ItemDetail view) {
|
||||
this.view = new WeakReference<>(view);
|
||||
this.item = getView().getItem();
|
||||
}
|
||||
@Override
|
||||
public void setModel(Model.Detail model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getCurrentItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getAppContext() {
|
||||
try {
|
||||
return getView().getAppContext();
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Context getActivityContext() {
|
||||
try {
|
||||
return getView().getActivityContext();
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void showMessage(String message) {
|
||||
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
// other impl <--
|
||||
|
||||
private View.ItemDetail getView() throws NullPointerException {
|
||||
if ( view != null )
|
||||
return view.get();
|
||||
else
|
||||
throw new NullPointerException("View is unavailable");
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ import java.util.List;
|
|||
import hikapro.com.backpack.R;
|
||||
import hikapro.com.backpack.model.ItemModel;
|
||||
import hikapro.com.backpack.model.Model;
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.model.entities.Set;
|
||||
import hikapro.com.backpack.presenter.adapters.CategoryListAdapter;
|
||||
import hikapro.com.backpack.presenter.adapters.ItemListAdapter;
|
||||
|
@ -35,11 +36,8 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
private Set set;
|
||||
private CategoryListAdapter categoryListAdapter;
|
||||
|
||||
public ItemListPresenter(View.ItemList view, Set set) {
|
||||
this.view = new WeakReference<>(view);
|
||||
this.set = set;
|
||||
public ItemListPresenter() {
|
||||
this.categoryListAdapter = new CategoryListAdapter(this);
|
||||
setModel(new ItemModel(this));
|
||||
}
|
||||
|
||||
// life cycle -->
|
||||
|
@ -113,7 +111,7 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
holder.title.setOnClickListener(new android.view.View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(android.view.View view) {
|
||||
showMessage("Position " + position + " Id " + holder.id);
|
||||
clickItem(holder.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -121,6 +119,11 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
public int getItemsCount(int categoryId) {
|
||||
return model.getItemsCount(categoryId);//TODO category Id
|
||||
}
|
||||
@Override
|
||||
public int getCategoriesCount() {
|
||||
return model.getCategoriesCount();
|
||||
}
|
||||
|
||||
|
||||
// recycler <--
|
||||
|
||||
|
@ -132,6 +135,14 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
categoryListAdapter.notifyItemAdapters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickItem(int itemId) {
|
||||
Item item = model.findItem(itemId);
|
||||
if (item != null)
|
||||
getView().showItemDetail(item);
|
||||
else
|
||||
showMessage(String.format("Item with Id %d is not found.", itemId));
|
||||
}
|
||||
// process <--
|
||||
|
||||
// other impl -->
|
||||
|
@ -139,6 +150,11 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
@Override
|
||||
public void setView(View.ItemList view) {
|
||||
this.view = new WeakReference<>(view);
|
||||
this.set = getView().getSet();
|
||||
}
|
||||
@Override
|
||||
public void setModel(Model.Item model) {
|
||||
this.model = model;
|
||||
}
|
||||
@Override
|
||||
public Context getAppContext() {
|
||||
|
@ -157,10 +173,6 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
}
|
||||
}
|
||||
@Override
|
||||
public void setModel(Model.Item model) {
|
||||
this.model = model;
|
||||
}
|
||||
@Override
|
||||
public void showMessage(String message) {
|
||||
Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
@ -174,10 +186,6 @@ public class ItemListPresenter implements Presenter.ItemList {
|
|||
throw new NullPointerException("View is unavailable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCategoriesCount() {
|
||||
return model.getCategoriesCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set getCurrentSet() {
|
||||
|
|
|
@ -6,8 +6,10 @@ import android.view.LayoutInflater;
|
|||
import android.view.ViewGroup;
|
||||
|
||||
import hikapro.com.backpack.model.Model;
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.model.entities.Set;
|
||||
import hikapro.com.backpack.view.recycler.CategoryViewHolder;
|
||||
import hikapro.com.backpack.view.recycler.DetailViewHolder;
|
||||
import hikapro.com.backpack.view.recycler.ItemViewHolder;
|
||||
import hikapro.com.backpack.view.recycler.SetViewHolder;
|
||||
|
||||
|
@ -49,6 +51,23 @@ public interface Presenter {
|
|||
Set getCurrentSet();
|
||||
void showMessage(String message);
|
||||
void onSaveInstanceState(Bundle outState);
|
||||
void clickItem(int itemId);
|
||||
}
|
||||
|
||||
interface ItemDetail extends Base {
|
||||
void setView(hikapro.com.backpack.view.View.ItemDetail view);
|
||||
void setModel(Model.Detail model);
|
||||
void notifyDataSetChanged();
|
||||
void showMessage(String message);
|
||||
int getItemsCount();
|
||||
void bindViewHolder(DetailViewHolder holder, int position);
|
||||
DetailViewHolder createViewHolder(ViewGroup parent, int viewType);
|
||||
void onDestroy(boolean isChangingConfiguration);
|
||||
android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
|
||||
void onSaveInstanceState(Bundle outState);
|
||||
Item getCurrentItem();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ public class SetListPresenter implements Presenter.SetList {
|
|||
|
||||
public SetListPresenter() {
|
||||
this.adapter = new SetListAdapter(this);
|
||||
setModel(new SetModel(this));
|
||||
}
|
||||
|
||||
// life cycle -->
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package hikapro.com.backpack.presenter.adapters;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import hikapro.com.backpack.presenter.Presenter;
|
||||
import hikapro.com.backpack.view.recycler.DetailViewHolder;
|
||||
|
||||
/**
|
||||
* Created by tariel on 23/04/16.
|
||||
*/
|
||||
public class ItemDetailAdapter extends RecyclerView.Adapter<DetailViewHolder> {
|
||||
|
||||
private Presenter.ItemDetail presenter;
|
||||
private int itemId;
|
||||
|
||||
public ItemDetailAdapter(Presenter.ItemDetail presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return presenter.getItemsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(DetailViewHolder holder, int position) {
|
||||
presenter.bindViewHolder(holder, position);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return presenter.createViewHolder(parent, viewType);
|
||||
}
|
||||
|
||||
public void setItemId(int id) {
|
||||
this.itemId = id;
|
||||
}
|
||||
}
|
|
@ -24,13 +24,16 @@ public interface View {
|
|||
interface ItemList extends Base {
|
||||
void showItemDetail(Item item);
|
||||
void setPresenter(Presenter.ItemList presenter);
|
||||
Set getSet();
|
||||
}
|
||||
interface ItemDetail extends Base {
|
||||
|
||||
void setPresenter(Presenter.ItemDetail presenter);
|
||||
Item getItem();
|
||||
}
|
||||
interface ActivityCallback {
|
||||
void startSetListFragment();
|
||||
void startItemListFragment(Set set);
|
||||
void startItemDetailFragment();
|
||||
void startItemDetailFragment(Item item);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package hikapro.com.backpack.view.fragments;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import hikapro.com.backpack.model.entities.Item;
|
||||
import hikapro.com.backpack.presenter.Presenter;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
*/
|
||||
public class ItemDetailFragment extends Fragment implements hikapro.com.backpack.view.View.ItemDetail {
|
||||
|
||||
private static final String BUNDLE_ITEM_KEY = "BUNDLE_ITEM_KEY";
|
||||
|
||||
private Presenter.ItemDetail presenter;
|
||||
private hikapro.com.backpack.view.View.ActivityCallback activityCallback;
|
||||
|
||||
|
||||
public ItemDetailFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
protected static ItemDetailFragment construct() {
|
||||
return new ItemDetailFragment();
|
||||
}
|
||||
|
||||
public static ItemDetailFragment newFromItem(Item item) {
|
||||
ItemDetailFragment ret = ItemDetailFragment.construct();
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(BUNDLE_ITEM_KEY, item);
|
||||
ret.setArguments(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// life cycle -->
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
activityCallback = (hikapro.com.backpack.view.View.ActivityCallback) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(context.toString()
|
||||
+ " must implement activityCallback");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
activityCallback = (hikapro.com.backpack.view.View.ActivityCallback) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement activityCallback");
|
||||
}
|
||||
Log.i(this.toString(), "onAttach");
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Log.i(this.toString(), "onCreate");
|
||||
}
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View view = presenter.onCreateView(inflater, container, savedInstanceState);
|
||||
presenter.setView(this);
|
||||
Log.i(this.toString(), "onCreateView");
|
||||
return view;
|
||||
}
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
Log.i(this.toString(), "onActivityCreated");
|
||||
}
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Log.i(this.toString(), "onStart");
|
||||
}
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.i(this.toString(), "onResume");
|
||||
}
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
Log.i(this.toString(), "onStop");
|
||||
}
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
presenter.onDestroy(true); // TODO isChangingConfigurations
|
||||
Log.i(this.toString(), "onDestroyView");
|
||||
}
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.onDestroy(false); // TODO isChangingConfigurations
|
||||
Log.i(this.toString(), "onDestroy");
|
||||
}
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
Log.i(this.toString(), "onDetach");
|
||||
}
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
Log.i(this.toString(), "onSaveInstanceState");
|
||||
}
|
||||
|
||||
// life cycle <--
|
||||
|
||||
@Override
|
||||
public void setPresenter(Presenter.ItemDetail presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getAppContext() {
|
||||
return this.getActivity().getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getActivityContext() {
|
||||
return this.getActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItem() {
|
||||
Bundle args = getArguments();
|
||||
Item item = (Item) args.getSerializable(BUNDLE_ITEM_KEY);
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -22,8 +22,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
|||
|
||||
private static final String BUNDLE_SET_KEY = "BUNDLE_SET_KEY";
|
||||
private hikapro.com.backpack.view.View.ActivityCallback activityCallback;
|
||||
private Presenter.ItemList presenter;
|
||||
|
||||
private Presenter.ItemList presenter;
|
||||
|
||||
public ItemListFragment() {
|
||||
// Required empty public constructor
|
||||
|
@ -38,7 +37,6 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
|||
Bundle args = new Bundle();
|
||||
args.putSerializable(BUNDLE_SET_KEY, set);
|
||||
ret.setArguments(args);
|
||||
ret.setPresenter(new ItemListPresenter(ret, set));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -74,6 +72,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
|||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View view = presenter.onCreateView(inflater, container, savedInstanceState);
|
||||
presenter.setView(this);
|
||||
Log.i(this.toString(), "onCreateView");
|
||||
return view;
|
||||
}
|
||||
|
@ -106,6 +105,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.onDestroy(false); // TODO isChangingConfigurations
|
||||
Log.i(this.toString(), "onDestroy");
|
||||
}
|
||||
@Override
|
||||
|
@ -123,7 +123,7 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
|||
|
||||
@Override
|
||||
public void showItemDetail(Item item) {
|
||||
//TODO not implemented
|
||||
activityCallback.startItemDetailFragment(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -141,4 +141,9 @@ public class ItemListFragment extends Fragment implements hikapro.com.backpack.v
|
|||
return this.getActivity();
|
||||
}
|
||||
|
||||
public Set getSet() {
|
||||
return (Set) getArguments().getSerializable(BUNDLE_SET_KEY);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ public class SetListFragment extends Fragment implements hikapro.com.backpack.vi
|
|||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setPresenter(new SetListPresenter());
|
||||
Log.i(this.toString(), "onCreate");
|
||||
}
|
||||
@Override
|
||||
|
@ -101,6 +100,7 @@ public class SetListFragment extends Fragment implements hikapro.com.backpack.vi
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.onDestroy(false); // TODO isChangingConfigurations
|
||||
Log.i(this.toString(), "onDestroy");
|
||||
}
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package hikapro.com.backpack.view.recycler;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import hikapro.com.backpack.R;
|
||||
|
||||
/**
|
||||
* Created by tariel on 23/04/16.
|
||||
*/
|
||||
public class DetailViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public TextView title;
|
||||
public TextView description;
|
||||
public ImageView photo;
|
||||
|
||||
public DetailViewHolder(View v) {
|
||||
super(v);
|
||||
setupViews(v);
|
||||
}
|
||||
|
||||
private void setupViews(View view) {
|
||||
title = (TextView) view.findViewById(R.id.item_title);
|
||||
description = (TextView) view.findViewById(R.id.item_description);
|
||||
photo = (ImageView) view.findViewById(R.id.item_photo);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="hikapro.com.backpack.view.fragments.ItemDetailFragment">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/item_detail_recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical">
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
|
||||
android:text="@string/hello_blank_fragment" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_photo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/item_title"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:contentDescription="Photo is here"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/item_photo"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="25dp"
|
||||
android:text="@string/hello_blank_fragment" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,8 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -1,3 +1,6 @@
|
|||
<resources>
|
||||
<string name="app_name">BackPack</string>
|
||||
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
|
|
Loading…
Reference in New Issue