diff --git a/app/build.gradle b/app/build.gradle index 9cfc069a2..7323d7a4c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,6 +59,7 @@ dependencies { compile 'com.github.pfichtner:durationformatter:0.1.1' compile 'de.cketti.library.changelog:ckchangelog:1.2.2' compile 'net.e175.klaus:solarpositioning:0.0.9' + compile 'com.github.woxthebox:draglistview:1.2.6' } check.dependsOn 'findbugs', 'pmd', 'lint' diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java index 96a73192a..65a64196b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AbstractAppManagerFragment.java @@ -9,13 +9,15 @@ import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.content.LocalBroadcastManager; +import android.support.v7.widget.LinearLayoutManager; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; -import android.widget.ListView; + +import com.woxthebox.draglistview.DragListView; import org.json.JSONObject; import org.slf4j.Logger; @@ -45,6 +47,14 @@ public abstract class AbstractAppManagerFragment extends Fragment { = "nodomain.freeyourgadget.gadgetbridge.appmanager.action.refresh_applist"; private static final Logger LOG = LoggerFactory.getLogger(AbstractAppManagerFragment.class); + + public void refreshList() { + } + + public String getSortFilename() { + return null; + } + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -86,7 +96,7 @@ public abstract class AbstractAppManagerFragment extends Fragment { protected final List appList = new ArrayList<>(); private GBDeviceAppAdapter mGBDeviceAppAdapter; private GBDeviceApp selectedApp = null; - private GBDevice mGBDevice = null; + protected GBDevice mGBDevice = null; protected List getSystemApps() { List systemApps = new ArrayList<>(); @@ -140,9 +150,6 @@ public abstract class AbstractAppManagerFragment extends Fragment { return cachedAppList; } - public void refreshList() { - } - @Override public void onCreate(@Nullable Bundle savedInstanceState) { mGBDevice = ((AppManagerActivity) getActivity()).getGBDevice(); @@ -166,20 +173,11 @@ public abstract class AbstractAppManagerFragment extends Fragment { View rootView = inflater.inflate(R.layout.activity_appmanager, container, false); - ListView appListView = (ListView) (rootView.findViewById(R.id.appListView)); - mGBDeviceAppAdapter = new GBDeviceAppAdapter(getContext(), appList); - appListView.setAdapter(this.mGBDeviceAppAdapter); - - appListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View v, int position, long id) { - UUID uuid = appList.get(position).getUUID(); - GBApplication.deviceService().onAppStart(uuid, true); - } - }); - - registerForContextMenu(appListView); - + DragListView appListView = (DragListView) (rootView.findViewById(R.id.appListView)); + appListView.setLayoutManager(new LinearLayoutManager(getActivity())); + mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_with_details, R.id.item_image, true, this); + appListView.setAdapter(mGBDeviceAppAdapter, false); + //registerForContextMenu(appListView); return rootView; } @@ -278,15 +276,6 @@ public abstract class AbstractAppManagerFragment extends Fragment { } } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: -// NavUtils.navigateUpFromSameTask(this); - return true; - } - return super.onOptionsItemSelected(item); - } @Override public void onDestroy() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java index f153b2de0..d71ead93f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerActivity.java @@ -3,7 +3,9 @@ package nodomain.freeyourgadget.gadgetbridge.activities.appmanager; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; +import android.support.v4.app.NavUtils; import android.support.v4.view.ViewPager; +import android.view.MenuItem; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdapter; @@ -83,4 +85,14 @@ public class AppManagerActivity extends AbstractGBFragmentActivity { } } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java index 02ea0720f..bfc28e469 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledApps.java @@ -5,4 +5,9 @@ public class AppManagerFragmentInstalledApps extends AbstractAppManagerFragment public void refreshList() { appList.addAll(getSystemApps()); } + @Override + + public String getSortFilename() { + return mGBDevice.getAddress() + ".watchapps"; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java index 58b59250e..14c916f05 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/appmanager/AppManagerFragmentInstalledWatchfaces.java @@ -5,4 +5,8 @@ public class AppManagerFragmentInstalledWatchfaces extends AbstractAppManagerFra public void refreshList() { appList.addAll(getSystemWatchfaces()); } + + public String getSortFilename() { + return mGBDevice.getAddress() + ".watchfaces"; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java index 2d78deff9..7f01d97f5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java @@ -1,73 +1,102 @@ package nodomain.freeyourgadget.gadgetbridge.adapter; -import android.content.Context; +import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; -import java.util.List; +import com.woxthebox.draglistview.DragItemAdapter; +import java.util.List; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp; /** * Adapter for displaying GBDeviceApp instances. */ -public class GBDeviceAppAdapter extends ArrayAdapter { - private final Context context; +public class GBDeviceAppAdapter extends DragItemAdapter { - public GBDeviceAppAdapter(Context context, List appList) { - super(context, 0, appList); + private final int mLayoutId; + private final int mGrabHandleId; + private final Fragment mParentFragment; + + public GBDeviceAppAdapter(List list, int layoutId, int grabHandleId, boolean dragOnLongPress, Fragment parentFragment) { + super(dragOnLongPress); + mLayoutId = layoutId; + mGrabHandleId = grabHandleId; + mParentFragment = parentFragment; + setHasStableIds(true); + setItemList(list); - this.context = context; } @Override - public View getView(int position, View view, ViewGroup parent) { - GBDeviceApp deviceApp = getItem(position); + public long getItemId(int position) { + return mItemList.get(position).getUUID().getLeastSignificantBits(); + } - if (view == null) { - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - view = inflater.inflate(R.layout.item_with_details, parent, false); - } - TextView deviceAppVersionAuthorLabel = (TextView) view.findViewById(R.id.item_details); - TextView deviceAppNameLabel = (TextView) view.findViewById(R.id.item_name); - ImageView deviceImageView = (ImageView) view.findViewById(R.id.item_image); + View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false); + return new ViewHolder(view); + } - deviceAppVersionAuthorLabel.setText(getContext().getString(R.string.appversion_by_creator, deviceApp.getVersion(), deviceApp.getCreator())); + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + GBDeviceApp deviceApp = mItemList.get(position); + + holder.mDeviceAppVersionAuthorLabel.setText(GBApplication.getContext().getString(R.string.appversion_by_creator, deviceApp.getVersion(), deviceApp.getCreator())); // FIXME: replace with small icons String appNameLabelText = deviceApp.getName(); if (deviceApp.isInCache() || deviceApp.isOnDevice()) { appNameLabelText += " (" + (deviceApp.isInCache() ? "C" : "") + (deviceApp.isOnDevice() ? "D" : "") + ")"; } - deviceAppNameLabel.setText(appNameLabelText); + holder.mDeviceAppNameLabel.setText(appNameLabelText); switch (deviceApp.getType()) { case APP_GENERIC: - deviceImageView.setImageResource(R.drawable.ic_watchapp); + holder.mDeviceImageView.setImageResource(R.drawable.ic_watchapp); break; case APP_ACTIVITYTRACKER: - deviceImageView.setImageResource(R.drawable.ic_activitytracker); + holder.mDeviceImageView.setImageResource(R.drawable.ic_activitytracker); break; case APP_SYSTEM: - case WATCHFACE_SYSTEM: - deviceImageView.setImageResource(R.drawable.ic_systemapp); + holder.mDeviceImageView.setImageResource(R.drawable.ic_systemapp); break; case WATCHFACE: - deviceImageView.setImageResource(R.drawable.ic_watchface); + holder.mDeviceImageView.setImageResource(R.drawable.ic_watchface); break; default: - deviceImageView.setImageResource(R.drawable.ic_watchapp); + holder.mDeviceImageView.setImageResource(R.drawable.ic_watchapp); } + } - return view; + public class ViewHolder extends DragItemAdapter.ViewHolder { + TextView mDeviceAppVersionAuthorLabel; + TextView mDeviceAppNameLabel; + ImageView mDeviceImageView; + + public ViewHolder(final View itemView) { + super(itemView, mGrabHandleId); + mDeviceAppVersionAuthorLabel = (TextView) itemView.findViewById(R.id.item_details); + mDeviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name); + mDeviceImageView = (ImageView) itemView.findViewById(R.id.item_image); + } + @Override + public void onItemClicked(View view) { + UUID uuid = mItemList.get(getAdapterPosition()).getUUID(); + GBApplication.deviceService().onAppStart(uuid, true); + } } } diff --git a/app/src/main/res/layout/activity_appmanager.xml b/app/src/main/res/layout/activity_appmanager.xml index 868f628fa..bdc6317c3 100644 --- a/app/src/main/res/layout/activity_appmanager.xml +++ b/app/src/main/res/layout/activity_appmanager.xml @@ -1,16 +1,17 @@ - + - + - + + + +