Skip to content
This repository has been archived by the owner on Aug 22, 2020. It is now read-only.

Commit

Permalink
Make IBreadcrumb abstract & implements Parcelable & Fix instance stat…
Browse files Browse the repository at this point in the history
…e save/restore

Signed-off-by: Fung Gwo <[email protected]>
  • Loading branch information
fython committed Mar 3, 2018
1 parent 171b5e5 commit 06a0120
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 128 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.iml
.gradle
/gradle.properties
/local.properties
/.idea
.DS_Store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected void onCreate(Bundle savedInstanceState) {
createItem("Path 1"),
createItem("Path 2")
)));
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() {
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
@Override
public void onNavigateBack(BreadcrumbItem item, int position) {
Snackbar.make(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void onItemClick(FileList.FileWrapper file) {
}
});

mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() {
mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback<BreadcrumbItem>() {
@Override
public void onNavigateBack(BreadcrumbItem item, int position) {
currentLocation = getPath(position);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import android.support.v7.widget.RecyclerView;
import android.view.*;
import android.widget.*;
import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;
import moe.feng.common.view.breadcrumbs.model.IBreadcrumbItem;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -18,29 +18,29 @@ class BreadcrumbsAdapter extends RecyclerView.Adapter<BreadcrumbsAdapter.ItemHol

private final int DROPDOWN_OFFSET_Y_FIX;

private ArrayList<BreadcrumbItem> items;
private List<IBreadcrumbItem> items = new ArrayList<>();
private BreadcrumbsCallback callback;

private BreadcrumbsView parent;

private int mPopupThemeId = -1;

public BreadcrumbsAdapter(BreadcrumbsView parent) {
this(parent, new ArrayList<BreadcrumbItem>());
this(parent, new ArrayList<IBreadcrumbItem>());
}

public BreadcrumbsAdapter(BreadcrumbsView parent, ArrayList<BreadcrumbItem> items) {
public BreadcrumbsAdapter(BreadcrumbsView parent, ArrayList<IBreadcrumbItem> items) {
this.parent = parent;
this.items = items;
DROPDOWN_OFFSET_Y_FIX = parent.getResources().getDimensionPixelOffset(R.dimen.dropdown_offset_y_fix_value);
}

public @NonNull ArrayList<BreadcrumbItem> getItems() {
return this.items;
public @NonNull <E extends IBreadcrumbItem> List<E> getItems() {
return (List<E>) this.items;
}

public void setItems(@NonNull ArrayList<BreadcrumbItem> items) {
this.items = items;
public <E extends IBreadcrumbItem> void setItems(@NonNull List<E> items) {
this.items = (List<IBreadcrumbItem>) items;
}

public void setCallback(@Nullable BreadcrumbsCallback callback) {
Expand All @@ -55,20 +55,21 @@ public void setPopupThemeId(@IdRes int popupThemeId) {
this.mPopupThemeId = popupThemeId;
}

@Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (viewType == R.layout.breadcrumbs_view_item_arrow) {
return new ArrowIconHolder(inflater.inflate(viewType, parent, false));
} else if (viewType == R.layout.breadcrumbs_view_item_text) {
return new BreadcrumbItemHolder(inflater.inflate(viewType, parent, false));
} else {
return null;
throw new IllegalArgumentException("Unknown view type:" + viewType);
}
}

@Override
public void onBindViewHolder(ItemHolder holder, int position) {
public void onBindViewHolder(@NonNull ItemHolder holder, int position) {
int viewType = getItemViewType(position);
int truePos = viewType == R.layout.breadcrumbs_view_item_arrow ? ((position - 1) / 2) + 1 : position / 2;
holder.setItem(items.get(truePos));
Expand All @@ -84,7 +85,7 @@ public int getItemViewType(int position) {
return position % 2 == 1 ? R.layout.breadcrumbs_view_item_arrow : R.layout.breadcrumbs_view_item_text;
}

class BreadcrumbItemHolder extends ItemHolder<BreadcrumbItem> {
class BreadcrumbItemHolder extends ItemHolder<IBreadcrumbItem> {

Button button;

Expand All @@ -102,9 +103,9 @@ public void onClick(View view) {
}

@Override
public void setItem(@NonNull BreadcrumbItem item) {
public void setItem(@NonNull IBreadcrumbItem item) {
super.setItem(item);
button.setText(item.getSelectedItem());
button.setText(item.getSelectedItem().toString());
button.setTextColor(
ViewUtils.getColorFromAttr(getContext(),
getAdapterPosition() == getItemCount() - 1
Expand All @@ -114,7 +115,7 @@ public void setItem(@NonNull BreadcrumbItem item) {

}

class ArrowIconHolder extends ItemHolder<BreadcrumbItem> {
class ArrowIconHolder extends ItemHolder<IBreadcrumbItem> {

ImageButton imageButton;
ListPopupWindow popupWindow;
Expand All @@ -138,7 +139,7 @@ public void onClick(View view) {
}

@Override
public void setItem(@NonNull BreadcrumbItem item) {
public void setItem(@NonNull IBreadcrumbItem item) {
super.setItem(item);
imageButton.setClickable(item.hasMoreSelect());
if (item.hasMoreSelect()) {
Expand All @@ -148,7 +149,6 @@ public void setItem(@NonNull BreadcrumbItem item) {
map.put("text", obj.toString());
list.add(map);
}
// Kotlin: item.getItems().map { "text" to it.toString() }
ListAdapter adapter = new SimpleAdapter(getPopupThemedContext(), list, R.layout.breadcrumbs_view_dropdown_item, new String[] {"text"}, new int[] {android.R.id.text1});
popupWindow.setAdapter(adapter);
popupWindow.setWidth(ViewUtils.measureContentWidth(getPopupThemedContext(), adapter));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package moe.feng.common.view.breadcrumbs;

import android.support.annotation.NonNull;

/**
* Interface definition for a callback to be invoked when BreadcrumbsView's item was clicked or changed.
*/
public interface BreadcrumbsCallback {
public interface BreadcrumbsCallback<E> {

/**
* Called when BreadcrumbsView's item has been clicked
*
* @param view Parent view
* @param position The position of clicked item
*/
void onItemClick(BreadcrumbsView view, int position);
void onItemClick(@NonNull BreadcrumbsView view, int position);

/**
* Called when BreadcrumbsView's item has been changed
Expand All @@ -20,6 +22,6 @@ public interface BreadcrumbsCallback {
* @param parentPosition The position of the parent item of changed item
* @param nextItem Next item title
*/
void onItemChange(BreadcrumbsView view, int parentPosition, String nextItem);
void onItemChange(@NonNull BreadcrumbsView view, int parentPosition, @NonNull E nextItem);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;

import moe.feng.common.view.breadcrumbs.model.IBreadcrumbItem;

import java.util.ArrayList;
import java.util.List;

public class BreadcrumbsView extends FrameLayout {

Expand All @@ -28,6 +30,9 @@ public class BreadcrumbsView extends FrameLayout {
*/
private int mPopupThemeId = -1;

private static final String KEY_SUPER_STATES = BuildConfig.APPLICATION_ID + ".superStates";
private static final String KEY_BREADCRUMBS = BuildConfig.APPLICATION_ID + ".breadcrumbs";

public BreadcrumbsView(Context context) {
this(context, null);
}
Expand Down Expand Up @@ -82,7 +87,7 @@ private void init() {
*
* @return Breadcrumb Items
*/
public @Nullable ArrayList<BreadcrumbItem> getItems() {
public @NonNull List<IBreadcrumbItem> getItems() {
return mAdapter.getItems();
}

Expand All @@ -91,19 +96,16 @@ private void init() {
*
* @return Current item
*/
public @Nullable BreadcrumbItem getCurrentItem() {
if (mAdapter.getItems().size() <= 0) {
return null;
}
return mAdapter.getItems().get(mAdapter.getItems().size() - 1);
public @NonNull <E extends IBreadcrumbItem> E getCurrentItem() {
return mAdapter.<E>getItems().get(mAdapter.getItems().size() - 1);
}

/**
* Set breadcrumb items list
*
* @param items Target list
*/
public void setItems(@Nullable ArrayList<BreadcrumbItem> items) {
public <E extends IBreadcrumbItem> void setItems(@NonNull List<E> items) {
mAdapter.setItems(items);
mAdapter.notifyDataSetChanged();
postDelayed(new Runnable() {
Expand All @@ -128,7 +130,7 @@ public void notifyItemChanged(int index) {
*
* @param item New item
*/
public void addItem(@NonNull BreadcrumbItem item) {
public <E extends IBreadcrumbItem> void addItem(@NonNull E item) {
int oldSize = mAdapter.getItemCount();
mAdapter.getItems().add(item);
mAdapter.notifyItemRangeInserted(oldSize, 2);
Expand Down Expand Up @@ -179,7 +181,7 @@ public void removeLastItem() {
* @see BreadcrumbsCallback
* @see DefaultBreadcrumbsCallback
*/
public void setCallback(@Nullable BreadcrumbsCallback callback) {
public <T> void setCallback(@Nullable BreadcrumbsCallback<T> callback) {
mAdapter.setCallback(callback);
}

Expand All @@ -189,46 +191,28 @@ public void setCallback(@Nullable BreadcrumbsCallback callback) {
* @return Callback
* @see BreadcrumbsCallback
*/
public @Nullable BreadcrumbsCallback getCallback() {
public @Nullable <T> BreadcrumbsCallback<T> getCallback() {
return mAdapter.getCallback();
}

// Save/Restore View Instance State
@Override
public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
State state = new State(super.onSaveInstanceState(), getItems());
bundle.putParcelable(State.STATE, state);
return bundle;
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_SUPER_STATES, super.onSaveInstanceState());
bundle.putParcelableArrayList(KEY_BREADCRUMBS, new ArrayList<>(mAdapter.getItems()));
return bundle;
}

@Override
public void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
State viewState = bundle.getParcelable(State.STATE);
super.onRestoreInstanceState(viewState.getSuperState());
setItems(viewState.getItems());
return;
Bundle bundle = (Bundle) state;
super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPER_STATES));
setItems(bundle.<IBreadcrumbItem>getParcelableArrayList(KEY_BREADCRUMBS));
return;
}
super.onRestoreInstanceState(BaseSavedState.EMPTY_STATE);
}

protected static class State extends BaseSavedState {

private static final String STATE = BreadcrumbsView.class.getSimpleName() + ".STATE";

private final ArrayList<BreadcrumbItem> items;

State(Parcelable superState, ArrayList<BreadcrumbItem> items) {
super(superState);
this.items = items;
}

ArrayList<BreadcrumbItem> getItems() {
return this.items;
}

}

}
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package moe.feng.common.view.breadcrumbs;

import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;
import moe.feng.common.view.breadcrumbs.model.IBreadcrumbItem;

/**
* Simple callback to be invoked when BreadcrumbsView's item was clicked or changed.
* Assist you to handle navigate actions.
*
* @see moe.feng.common.view.breadcrumbs.BreadcrumbsCallback
*/
public abstract class DefaultBreadcrumbsCallback implements BreadcrumbsCallback {
public abstract class DefaultBreadcrumbsCallback<T extends IBreadcrumbItem> implements BreadcrumbsCallback {

@Override
public void onItemClick(BreadcrumbsView view, int position) {
if (position == view.getItems().size() - 1) return;
view.removeItemAfter(position + 1);
this.onNavigateBack(view.getItems().get(position), position);
this.onNavigateBack((T) view.getItems().get(position), position);
}

@Override
public void onItemChange(BreadcrumbsView view, int parentPosition, String nextItem) {
BreadcrumbItem nextBreadcrumb = view.getItems().get(parentPosition + 1);
public void onItemChange(BreadcrumbsView view, int parentPosition, Object nextItem) {
T nextBreadcrumb = (T) view.getItems().get(parentPosition + 1);
nextBreadcrumb.setSelectedItem(nextItem);
view.removeItemAfter(parentPosition + 2);
if (parentPosition + 2 >= view.getItems().size()) {
Expand All @@ -34,14 +34,14 @@ public void onItemChange(BreadcrumbsView view, int parentPosition, String nextIt
* @param item The item that was navigated to
* @param position The position of new location
*/
public abstract void onNavigateBack(BreadcrumbItem item, int position);
public abstract void onNavigateBack(T item, int position);

/**
* Called when page should navigate to the location where was changed by popup menu
*
* @param newItem The item that was navigated to
* @param changedPosition The position of changed location
*/
public abstract void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition);
public abstract void onNavigateNewLocation(T newItem, int changedPosition);

}
Loading

0 comments on commit 06a0120

Please sign in to comment.