Reorder in DApp drawer list introduced. On app launch the first DApp from list is opened (instead of console by default)

This commit is contained in:
Yaroslav Berezanskyi 2015-08-28 14:34:51 +03:00
parent e154aa83dd
commit 85a0ab95a9
13 changed files with 347 additions and 58 deletions

View File

@ -15,6 +15,7 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
@ -41,6 +42,7 @@ import io.syng.adapter.DAppDrawerAdapter;
import io.syng.adapter.DAppDrawerAdapter.OnDAppClickListener;
import io.syng.adapter.ProfileDrawerAdapter;
import io.syng.adapter.ProfileDrawerAdapter.OnProfileClickListener;
import io.syng.adapter.helper.SimpleItemTouchHelperCallback;
import io.syng.entity.Dapp;
import io.syng.entity.Profile;
import io.syng.fragment.profile.ProfileDialogFragment;
@ -82,6 +84,8 @@ public abstract class BaseActivity extends AppCompatActivity implements
protected abstract void onDAppClick(Dapp dapp);
private ItemTouchHelper mItemTouchHelper;
@SuppressLint("InflateParams")
@Override
public void setContentView(final int layoutResID) {
@ -105,6 +109,7 @@ public abstract class BaseActivity extends AppCompatActivity implements
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
GeneralUtil.hideKeyBoard(mSearchTextView, BaseActivity.this);
mDAppsDrawerAdapter.setEditModeEnabled(false);
if (!isDrawerFrontViewActive()) {
flipDrawer();
}
@ -132,12 +137,22 @@ public abstract class BaseActivity extends AppCompatActivity implements
updateCurrentProfileName();
populateProfiles();
RecyclerView DAppsRecyclerView = (RecyclerView) findViewById(R.id.dapp_drawer_recycler_view);
DAppsRecyclerView.setHasFixedSize(true);
RecyclerView dAppsRecyclerView = (RecyclerView) findViewById(R.id.dapp_drawer_recycler_view);
dAppsRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager1 = new LinearLayoutManager(this);
DAppsRecyclerView.setLayoutManager(layoutManager1);
mDAppsDrawerAdapter = new DAppDrawerAdapter(new ArrayList<Dapp>(), this);
DAppsRecyclerView.setAdapter(mDAppsDrawerAdapter);
dAppsRecyclerView.setLayoutManager(layoutManager1);
mDAppsDrawerAdapter = new DAppDrawerAdapter(this, this, new DAppDrawerAdapter.OnStartDragListener() {
@Override
public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
mItemTouchHelper.startDrag(viewHolder);
}
});
dAppsRecyclerView.setAdapter(mDAppsDrawerAdapter);
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mDAppsDrawerAdapter);
mItemTouchHelper = new ItemTouchHelper(callback);
mItemTouchHelper.attachToRecyclerView(dAppsRecyclerView);
populateDApps();
mHeaderImageView = (ImageView) findViewById(R.id.iv_header);
@ -232,6 +247,7 @@ public abstract class BaseActivity extends AppCompatActivity implements
dapps.add(item);
}
}
mDAppsDrawerAdapter.setEditModeEnabled(false);
mDAppsDrawerAdapter.swapData(dapps);
}
@ -279,6 +295,10 @@ public abstract class BaseActivity extends AppCompatActivity implements
closeDrawer(DRAWER_CLOSE_DELAY_LONG);
break;
case R.id.drawer_header_item:
if (isDrawerFrontViewActive()) {
mDAppsDrawerAdapter.setEditModeEnabled(false);
GeneralUtil.hideKeyBoard(mSearchTextView, BaseActivity.this);
}
flipDrawer();
break;
}
@ -290,7 +310,6 @@ public abstract class BaseActivity extends AppCompatActivity implements
mFrontView.setVisibility(View.GONE);
mBackView.setVisibility(VISIBLE);
imageView.setImageResource(R.drawable.ic_arrow_drop_up_black_24dp);
GeneralUtil.hideKeyBoard(mSearchTextView, BaseActivity.this);
} else {
mBackView.setVisibility(View.GONE);
mFrontView.setVisibility(VISIBLE);
@ -329,8 +348,9 @@ public abstract class BaseActivity extends AppCompatActivity implements
GeneralUtil.showProfileImportDialog(this);
}
@Override
public void onDAppPress(final Dapp dapp) {
public void onDAppEdit(final Dapp dapp) {
GeneralUtil.showDAppEditDialog(dapp, this);
}

View File

@ -8,6 +8,7 @@ import io.syng.R;
import io.syng.entity.Dapp;
import io.syng.fragment.ConsoleFragment;
import io.syng.fragment.WebViewFragment;
import io.syng.util.ProfileManager;
public class MainActivity extends BaseActivity {
@ -18,9 +19,15 @@ public class MainActivity extends BaseActivity {
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
replaceFragment(new ConsoleFragment());
if (!ProfileManager.getCurrentProfile().getDapps().isEmpty()) {
Dapp dapp = ProfileManager.getCurrentProfile().getDapps().get(0);
onDAppItemClick(dapp);
}else{
replaceFragment(new ConsoleFragment());
}
}
processIntent(getIntent());
}
@Override

View File

@ -1,39 +1,59 @@
package io.syng.adapter;
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import io.syng.R;
import io.syng.adapter.helper.ItemTouchHelperAdapter;
import io.syng.entity.Dapp;
import io.syng.util.ProfileManager;
public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ItemTouchHelperAdapter {
private static final int TYPE_FOOTER = 10;
private static final int TYPE_SIMPLE_ITEM = 20;
private static final int TYPE_CONTINUE_SEARCH = 30;
private final OnDAppClickListener mListener;
private final OnDAppClickListener mDAppClickListener;
private final OnStartDragListener mStartDragListener;
public interface OnDAppClickListener {
void onDAppItemClick(Dapp dapp);
void onDAppPress(Dapp dapp);
void onDAppEdit(Dapp dapp);
void onDAppAdd();
void onDAppContinueSearch();
}
private List<Dapp> mDataSet;
private boolean continueSearch;
public interface OnStartDragListener {
void onStartDrag(RecyclerView.ViewHolder viewHolder);
}
public DAppDrawerAdapter(List<Dapp> data, OnDAppClickListener listener) {
this.mDataSet = data;
mListener = listener;
continueSearch = data.isEmpty();
private List<Dapp> mDataSet;
private boolean mContinueSearch;
private boolean mEditModeEnabled;
// private Animation mAnimFadeIn, mAnimFadeOut;
public DAppDrawerAdapter(Context context, OnDAppClickListener DAppClickListener, OnStartDragListener startDragListener) {
this.mDataSet = new ArrayList<>();
mDAppClickListener = DAppClickListener;
mStartDragListener = startDragListener;
mContinueSearch = mDataSet.isEmpty();
// mAnimFadeIn = AnimationUtils.loadAnimation(context,
// R.anim.fade_in);
// mAnimFadeOut = AnimationUtils.loadAnimation(context,
// R.anim.fade_out);
}
@Override
@ -57,34 +77,64 @@ public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof SimpleViewHolder) {
SimpleViewHolder myHolder = (SimpleViewHolder) holder;
final SimpleViewHolder myHolder = (SimpleViewHolder) holder;
final Dapp dapp = mDataSet.get(position);
myHolder.setting.setVisibility(mEditModeEnabled ? View.VISIBLE : View.GONE);
myHolder.reorder.setVisibility(mEditModeEnabled ? View.VISIBLE : View.GONE);
// myHolder.setting.startAnimation(mEditModeEnabled ? mAnimFadeIn : mAnimFadeOut);
// myHolder.reorder.startAnimation(mEditModeEnabled ? mAnimFadeIn : mAnimFadeOut);
myHolder.nameTextView.setText(dapp.getName());
myHolder.item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.onDAppItemClick(dapp);
if (!mEditModeEnabled) {
if (mDAppClickListener != null) {
mDAppClickListener.onDAppItemClick(dapp);
}
}else{
setEditModeEnabled(false);
}
}
});
myHolder.setting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mDAppClickListener != null) {
mDAppClickListener.onDAppEdit(dapp);
}
}
});
myHolder.item.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mListener != null) {
mListener.onDAppPress(dapp);
}
mEditModeEnabled = !mEditModeEnabled;
notifyDataSetChanged();
return true;
}
});
myHolder.reorder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
mStartDragListener.onStartDrag(myHolder);
}
return false;
}
});
}
if (holder instanceof FooterViewHolder) {
FooterViewHolder myHolder = (FooterViewHolder) holder;
myHolder.addView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.onDAppAdd();
if (mDAppClickListener != null) {
mDAppClickListener.onDAppAdd();
}
}
});
@ -94,17 +144,26 @@ public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
myHolder.continueSearchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
mListener.onDAppContinueSearch();
if (mDAppClickListener != null) {
mDAppClickListener.onDAppContinueSearch();
}
}
});
}
}
public void setEditModeEnabled(boolean editModeEnabled) {
if (editModeEnabled != mEditModeEnabled) {
mEditModeEnabled = editModeEnabled;
notifyDataSetChanged();
}
}
@Override
public int getItemCount() {
return continueSearch ? mDataSet.size() + 2 : mDataSet.size() + 1;
return mContinueSearch ? mDataSet.size() + 2 : mDataSet.size() + 1;
}
@Override
@ -119,11 +178,11 @@ public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
}
private boolean isPositionFooter(int position) {
return continueSearch ? position == mDataSet.size() + 1 : position == mDataSet.size();
return mContinueSearch ? position == mDataSet.size() + 1 : position == mDataSet.size();
}
private boolean isPositionContinueItem(int position) {
return continueSearch && position == mDataSet.size();
return mContinueSearch && position == mDataSet.size();
}
public void clear() {
@ -139,24 +198,36 @@ public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
public void swapData(List<Dapp> items) {
mDataSet.clear();
mDataSet.addAll(items);
continueSearch = mDataSet.isEmpty();
mContinueSearch = mDataSet.isEmpty();
notifyDataSetChanged();
}
static class SimpleViewHolder extends RecyclerView.ViewHolder {
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(mDataSet, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
ProfileManager.reorderDAppsInProfile(ProfileManager.getCurrentProfile(), fromPosition, toPosition);
return true;
}
private static class SimpleViewHolder extends RecyclerView.ViewHolder {
private TextView nameTextView;
private View item;
private ImageView reorder;
private ImageView setting;
public SimpleViewHolder(View v) {
super(v);
nameTextView = (TextView) v.findViewById(R.id.text);
item = v.findViewById(R.id.ll_dapp_item);
reorder = (ImageView) v.findViewById(R.id.iv_reorder);
setting = (ImageView) v.findViewById(R.id.iv_settings);
}
}
static class FooterViewHolder extends RecyclerView.ViewHolder {
private static class FooterViewHolder extends RecyclerView.ViewHolder {
private View addView;
@ -167,7 +238,7 @@ public class DAppDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
}
static class ContinueSearchViewHolder extends RecyclerView.ViewHolder {
private static class ContinueSearchViewHolder extends RecyclerView.ViewHolder {
private View continueSearchView;

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2015 Paul Burke
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.syng.adapter.helper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
/**
* Interface to listen for a move or dismissal event from a {@link ItemTouchHelper.Callback}.
*/
public interface ItemTouchHelperAdapter {
/**
* Called when an item has been dragged far enough to trigger a move. This is called every time
* an item is shifted, and <strong>not</strong> at the end of a "drop" event.<br/>
* <br/>
* Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after
* adjusting the underlying data to reflect this move.
*
* @param fromPosition The start position of the moved item.
* @param toPosition Then resolved position of the moved item.
* @return True if the item was moved to the new adapter position.
* @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
* @see RecyclerView.ViewHolder#getAdapterPosition()
*/
boolean onItemMove(int fromPosition, int toPosition);
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2015 Paul Burke
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.syng.adapter.helper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
/**
* An implementation of {@link ItemTouchHelper.Callback} that enables basic drag & drop and
* swipe-to-dismiss. Drag events are automatically started by an item long-press.<br/>
* </br/>
* Expects the <code>RecyclerView.Adapter</code> to listen for {@link
* ItemTouchHelperAdapter} callbacks and the <code>RecyclerView.ViewHolder</code> to implement
* {@link ItemTouchHelperViewHolder}.
*
* @author Paul Burke (ipaulpro)
*/
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
public static final float ALPHA_FULL = 1.0f;
private final ItemTouchHelperAdapter mAdapter;
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return false;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (source.getItemViewType() != target.getItemViewType()) {
return false;
}
// Notify the adapter of the move
mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}
// @Override
// public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
// if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
// // Fade out the view as it is swiped out of the parent's bounds
// final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
// viewHolder.itemView.setAlpha(alpha);
// viewHolder.itemView.setTranslationX(dX);
// } else {
// super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
// }
// }
// @Override
// public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// // We only want the active item to change
// if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
// if (viewHolder instanceof ItemTouchHelperViewHolder) {
// // Let the view holder know that this item is being moved or dragged
// ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
// itemViewHolder.onItemSelected();
// }
// }
//
// super.onSelectedChanged(viewHolder, actionState);
// }
//
// @Override
// public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// super.clearView(recyclerView, viewHolder);
//
// viewHolder.itemView.setAlpha(ALPHA_FULL);
//
// if (viewHolder instanceof ItemTouchHelperViewHolder) {
// // Tell the view holder it's time to restore the idle state
// ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
// itemViewHolder.onItemClear();
// }
// }
}

View File

@ -55,7 +55,7 @@ public final class PrefsUtil {
return getInstance().mContext.getString(resourceId);
}
private static void saveProfiles(ArrayList<Profile> profiles) {
public static void saveProfiles(ArrayList<Profile> profiles) {
try {
getEditor().putString(PROFILES_KEY, ObjectSerializer.serialize(profiles)).commit();
} catch (Exception e) {
@ -75,26 +75,6 @@ public final class PrefsUtil {
return profiles;
}
public static void updateProfile(Profile profile) {
ArrayList<Profile> profiles = getProfiles();
for (Profile item : profiles) {
if (item.getId().equals(profile.getId())) {
int index = profiles.indexOf(item);
profiles.set(index, profile);
saveProfiles(profiles);
break;
}
}
}
public static boolean addProfile(Profile profile) {
ArrayList<Profile> profiles = PrefsUtil.getProfiles();
profiles.add(profile);
saveProfiles(profiles);
return true;
}
public static void setCurrentProfileId(String profileId) {
getEditor().putString(CURRENT_PROFILE_KEY, profileId).commit();
}

View File

@ -4,6 +4,7 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import io.syng.app.SyngApplication;
@ -40,12 +41,22 @@ public final class ProfileManager {
}
public static void addProfile(Profile profile) {
PrefsUtil.addProfile(profile);
ArrayList<Profile> profiles = PrefsUtil.getProfiles();
profiles.add(profile);
PrefsUtil.saveProfiles(profiles);
notifyListener();
}
public static void updateProfile(Profile profile) {
PrefsUtil.updateProfile(profile);
ArrayList<Profile> profiles = getProfiles();
for (Profile item : profiles) {
if (item.getId().equals(profile.getId())) {
int index = profiles.indexOf(item);
profiles.set(index, profile);
PrefsUtil.saveProfiles(profiles);
break;
}
}
notifyListener();
}
@ -101,6 +112,22 @@ public final class ProfileManager {
notifyListener();
}
public static void reorderDAppsInProfile(Profile profile, int fromPosition, int toPosition) {
List<Dapp> dapps = profile.getDapps();
Collections.swap(dapps, fromPosition, toPosition);
profile.setDapps(dapps);
ArrayList<Profile> profiles = getProfiles();
for (Profile item : profiles) {
if (item.getId().equals(profile.getId())) {
int index = profiles.indexOf(item);
profiles.set(index, profile);
PrefsUtil.saveProfiles(profiles);
break;
}
}
}
@Nullable
public static Profile getProfileById(String profileId) {
List<Profile> profiles = ProfileManager.getProfiles();

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

View File

@ -6,7 +6,8 @@
android:layout_height="?attr/listPreferredItemHeightSmall"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal">
android:orientation="horizontal"
>
<ImageView
android:layout_width="wrap_content"
@ -27,6 +28,34 @@
tools:text="Test text"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_weight="1"
android:gravity="center_vertical|end"
>
<ImageView
android:id="@+id/iv_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:src="@drawable/ic_settings_black_24dp"
android:tint="@color/drawer_icon_color"/>
<ImageView
android:id="@+id/iv_reorder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:src="@drawable/ic_reorder_black_24dp"
android:tint="@color/drawer_icon_color"/>
</LinearLayout>
</LinearLayout>