mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-03 13:37:32 +01:00
Fossil Hybrid HR: Add watchface preview images in the app manager
This commit is contained in:
parent
ec5e51b9a9
commit
48212d4185
@ -23,6 +23,8 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -47,7 +49,6 @@ import java.util.UUID;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
@ -61,6 +62,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GridAutoFitLayoutManager;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.PebbleUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.PebbleUtils;
|
||||||
|
|
||||||
|
|
||||||
@ -122,8 +124,9 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
String appCreator = intent.getStringExtra("app_creator" + i);
|
String appCreator = intent.getStringExtra("app_creator" + i);
|
||||||
UUID uuid = UUID.fromString(intent.getStringExtra("app_uuid" + i));
|
UUID uuid = UUID.fromString(intent.getStringExtra("app_uuid" + i));
|
||||||
GBDeviceApp.Type appType = GBDeviceApp.Type.values()[intent.getIntExtra("app_type" + i, 0)];
|
GBDeviceApp.Type appType = GBDeviceApp.Type.values()[intent.getIntExtra("app_type" + i, 0)];
|
||||||
|
Bitmap previewImage = getAppPreviewImage(uuid.toString());
|
||||||
|
|
||||||
GBDeviceApp app = new GBDeviceApp(uuid, appName, appCreator, "", appType);
|
GBDeviceApp app = new GBDeviceApp(uuid, appName, appCreator, "", appType, previewImage);
|
||||||
app.setOnDevice(true);
|
app.setOnDevice(true);
|
||||||
if (filterApp(app)) {
|
if (filterApp(app)) {
|
||||||
appList.add(app);
|
appList.add(app);
|
||||||
@ -131,6 +134,20 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Bitmap getAppPreviewImage(String name) {
|
||||||
|
Bitmap previewImage = null;
|
||||||
|
try {
|
||||||
|
File cacheDir = mCoordinator.getAppCacheDir();
|
||||||
|
File previewImgFile = new File(cacheDir, name + "_preview.png");
|
||||||
|
if (previewImgFile.exists()) {
|
||||||
|
previewImage = BitmapFactory.decodeFile(previewImgFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warn("Couldn't load watch app preview image", e);
|
||||||
|
}
|
||||||
|
return previewImage;
|
||||||
|
}
|
||||||
|
|
||||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@ -183,7 +200,7 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
try {
|
try {
|
||||||
String jsonstring = FileUtils.getStringFromFile(jsonFile);
|
String jsonstring = FileUtils.getStringFromFile(jsonFile);
|
||||||
JSONObject json = new JSONObject(jsonstring);
|
JSONObject json = new JSONObject(jsonstring);
|
||||||
cachedAppList.add(new GBDeviceApp(json, configFile.exists()));
|
cachedAppList.add(new GBDeviceApp(json, configFile.exists(), getAppPreviewImage(baseName)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.info("could not read json file for " + baseName);
|
LOG.info("could not read json file for " + baseName);
|
||||||
if (mGBDevice.getType() == DeviceType.PEBBLE) {
|
if (mGBDevice.getType() == DeviceType.PEBBLE) {
|
||||||
@ -293,8 +310,8 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
appListView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
appListView.setLayoutManager(new GridAutoFitLayoutManager(getActivity(), 300));
|
||||||
mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_pebble_watchapp, this);
|
mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_appmanager_watchapp, this);
|
||||||
appListView.setAdapter(mGBDeviceAppAdapter);
|
appListView.setAdapter(mGBDeviceAppAdapter);
|
||||||
|
|
||||||
ItemTouchHelper.Callback appItemTouchHelperCallback = new AppItemTouchHelperCallback(mGBDeviceAppAdapter);
|
ItemTouchHelper.Callback appItemTouchHelperCallback = new AppItemTouchHelperCallback(mGBDeviceAppAdapter);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.adapter;
|
package nodomain.freeyourgadget.gadgetbridge.adapter;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -29,6 +30,10 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment;
|
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment;
|
||||||
@ -39,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class GBDeviceAppAdapter extends RecyclerView.Adapter<GBDeviceAppAdapter.AppViewHolder> {
|
public class GBDeviceAppAdapter extends RecyclerView.Adapter<GBDeviceAppAdapter.AppViewHolder> {
|
||||||
|
private final Logger LOG = LoggerFactory.getLogger(GBDeviceAppAdapter.class);
|
||||||
|
|
||||||
private final int mLayoutId;
|
private final int mLayoutId;
|
||||||
private final List<GBDeviceApp> appList;
|
private final List<GBDeviceApp> appList;
|
||||||
@ -79,6 +85,14 @@ public class GBDeviceAppAdapter extends RecyclerView.Adapter<GBDeviceAppAdapter.
|
|||||||
String appNameLabelText = deviceApp.getName();
|
String appNameLabelText = deviceApp.getName();
|
||||||
holder.mDeviceAppNameLabel.setText(appNameLabelText);
|
holder.mDeviceAppNameLabel.setText(appNameLabelText);
|
||||||
|
|
||||||
|
Bitmap previewImage = deviceApp.getPreviewImage();
|
||||||
|
holder.mPreviewImage.setImageBitmap(previewImage);
|
||||||
|
if (previewImage == null) {
|
||||||
|
holder.mPreviewImage.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
holder.mPreviewImage.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
switch (deviceApp.getType()) {
|
switch (deviceApp.getType()) {
|
||||||
case APP_GENERIC:
|
case APP_GENERIC:
|
||||||
holder.mDeviceImageView.setImageResource(R.drawable.ic_watchapp);
|
holder.mDeviceImageView.setImageResource(R.drawable.ic_watchapp);
|
||||||
@ -130,6 +144,7 @@ public class GBDeviceAppAdapter extends RecyclerView.Adapter<GBDeviceAppAdapter.
|
|||||||
final TextView mDeviceAppNameLabel;
|
final TextView mDeviceAppNameLabel;
|
||||||
final ImageView mDeviceImageView;
|
final ImageView mDeviceImageView;
|
||||||
final ImageView mDragHandle;
|
final ImageView mDragHandle;
|
||||||
|
final ImageView mPreviewImage;
|
||||||
|
|
||||||
AppViewHolder(View itemView) {
|
AppViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
@ -137,6 +152,7 @@ public class GBDeviceAppAdapter extends RecyclerView.Adapter<GBDeviceAppAdapter.
|
|||||||
mDeviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name);
|
mDeviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name);
|
||||||
mDeviceImageView = (ImageView) itemView.findViewById(R.id.item_image);
|
mDeviceImageView = (ImageView) itemView.findViewById(R.id.item_image);
|
||||||
mDragHandle = (ImageView) itemView.findViewById(R.id.drag_handle);
|
mDragHandle = (ImageView) itemView.findViewById(R.id.drag_handle);
|
||||||
|
mPreviewImage = (ImageView) itemView.findViewById(R.id.item_preview_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ public class FossilFileReader {
|
|||||||
} else {
|
} else {
|
||||||
mAppKeys.put("type", "APP_GENERIC");
|
mAppKeys.put("type", "APP_GENERIC");
|
||||||
}
|
}
|
||||||
app = new GBDeviceApp(mAppKeys, false);
|
app = new GBDeviceApp(mAppKeys, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<String> parseAppFilenames(ByteBuffer buf, int untilPosition, boolean cutTrailingNull) {
|
private ArrayList<String> parseAppFilenames(ByteBuffer buf, int untilPosition, boolean cutTrailingNull) {
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.impl;
|
package nodomain.freeyourgadget.gadgetbridge.impl;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@ -31,6 +33,20 @@ public class GBDeviceApp {
|
|||||||
private final boolean inCache;
|
private final boolean inCache;
|
||||||
private boolean isOnDevice;
|
private boolean isOnDevice;
|
||||||
private final boolean configurable;
|
private final boolean configurable;
|
||||||
|
private final Bitmap previewImage;
|
||||||
|
|
||||||
|
public GBDeviceApp(UUID uuid, String name, String creator, String version, Type type, Bitmap previewImage) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.name = name;
|
||||||
|
this.creator = creator;
|
||||||
|
this.version = version;
|
||||||
|
this.type = type;
|
||||||
|
this.previewImage = previewImage;
|
||||||
|
//FIXME: do not assume
|
||||||
|
this.inCache = false;
|
||||||
|
this.configurable = false;
|
||||||
|
this.isOnDevice = false;
|
||||||
|
}
|
||||||
|
|
||||||
public GBDeviceApp(UUID uuid, String name, String creator, String version, Type type) {
|
public GBDeviceApp(UUID uuid, String name, String creator, String version, Type type) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
@ -38,13 +54,14 @@ public class GBDeviceApp {
|
|||||||
this.creator = creator;
|
this.creator = creator;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.previewImage = null;
|
||||||
//FIXME: do not assume
|
//FIXME: do not assume
|
||||||
this.inCache = false;
|
this.inCache = false;
|
||||||
this.configurable = false;
|
this.configurable = false;
|
||||||
this.isOnDevice = false;
|
this.isOnDevice = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBDeviceApp(JSONObject json, boolean configurable) {
|
public GBDeviceApp(JSONObject json, boolean configurable, Bitmap previewImage) {
|
||||||
UUID uuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
UUID uuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||||
String name = "";
|
String name = "";
|
||||||
String creator = "";
|
String creator = "";
|
||||||
@ -66,6 +83,7 @@ public class GBDeviceApp {
|
|||||||
this.creator = creator;
|
this.creator = creator;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.previewImage = previewImage;
|
||||||
//FIXME: do not assume
|
//FIXME: do not assume
|
||||||
this.inCache = true;
|
this.inCache = true;
|
||||||
this.configurable = configurable;
|
this.configurable = configurable;
|
||||||
@ -103,6 +121,10 @@ public class GBDeviceApp {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap getPreviewImage() {
|
||||||
|
return previewImage;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
WATCHFACE,
|
WATCHFACE,
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
// https://gist.github.com/omidraha/af3aa017d4ec06342bdc03c49d4b83b1
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/30256880/538284
|
||||||
|
// https://stackoverflow.com/a/42241730/538284
|
||||||
|
// https://stackoverflow.com/a/38082715/538284
|
||||||
|
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
public class GridAutoFitLayoutManager extends GridLayoutManager {
|
||||||
|
private int mColumnWidth;
|
||||||
|
private boolean mColumnWidthChanged = true;
|
||||||
|
private boolean mWidthChanged = true;
|
||||||
|
private int mWidth;
|
||||||
|
private static final int sColumnWidth = 200; // assume cell width of 200dp
|
||||||
|
|
||||||
|
public GridAutoFitLayoutManager(Context context, int columnWidth) {
|
||||||
|
/* Initially set spanCount to 1, will be changed automatically later. */
|
||||||
|
super(context, 1);
|
||||||
|
setColumnWidth(checkedColumnWidth(context, columnWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAutoFitLayoutManager(Context context, int columnWidth, int orientation, boolean reverseLayout) {
|
||||||
|
/* Initially set spanCount to 1, will be changed automatically later. */
|
||||||
|
super(context, 1, orientation, reverseLayout);
|
||||||
|
setColumnWidth(checkedColumnWidth(context, columnWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int checkedColumnWidth(Context context, int columnWidth) {
|
||||||
|
if (columnWidth <= 0) {
|
||||||
|
columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sColumnWidth,
|
||||||
|
context.getResources().getDisplayMetrics());
|
||||||
|
} else {
|
||||||
|
columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, columnWidth,
|
||||||
|
context.getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
return columnWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setColumnWidth(int newColumnWidth) {
|
||||||
|
if (newColumnWidth > 0 && newColumnWidth != mColumnWidth) {
|
||||||
|
mColumnWidth = newColumnWidth;
|
||||||
|
mColumnWidthChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
|
||||||
|
int width = getWidth();
|
||||||
|
int height = getHeight();
|
||||||
|
|
||||||
|
if (width != mWidth) {
|
||||||
|
mWidthChanged = true;
|
||||||
|
mWidth = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mColumnWidthChanged && mColumnWidth > 0 && width > 0 && height > 0
|
||||||
|
|| mWidthChanged) {
|
||||||
|
int totalSpace;
|
||||||
|
if (getOrientation() == VERTICAL) {
|
||||||
|
totalSpace = width - getPaddingRight() - getPaddingLeft();
|
||||||
|
} else {
|
||||||
|
totalSpace = height - getPaddingTop() - getPaddingBottom();
|
||||||
|
}
|
||||||
|
int spanCount = Math.max(1, totalSpace / mColumnWidth);
|
||||||
|
setSpanCount(spanCount);
|
||||||
|
mColumnWidthChanged = false;
|
||||||
|
mWidthChanged = false;
|
||||||
|
}
|
||||||
|
super.onLayoutChildren(recycler, state);
|
||||||
|
}
|
||||||
|
}
|
87
app/src/main/res/layout/item_appmanager_watchapp.xml
Normal file
87
app/src/main/res/layout/item_appmanager_watchapp.xml
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/appmanager_item_card_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
app:cardCornerRadius="3dp"
|
||||||
|
app:cardElevation="3dp"
|
||||||
|
app:contentPadding="8dp">
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/item_preview_image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/activatedBackgroundIndicator"
|
||||||
|
android:minHeight="60dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/item_image"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:contentDescription="@string/candidate_item_device_image" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignWithParentIfMissing="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_toEndOf="@+id/item_image"
|
||||||
|
android:layout_toStartOf="@+id/drag_handle"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:paddingTop="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:scrollHorizontally="false"
|
||||||
|
android:text="Item Name"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_details"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Item Description"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/drag_handle"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:contentDescription="drag handle"
|
||||||
|
app:tint="@color/secondarytext"
|
||||||
|
app:srcCompat="@drawable/ic_drag_handle" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
@ -1,63 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?android:attr/activatedBackgroundIndicator"
|
|
||||||
android:minHeight="60dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/item_image"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:contentDescription="@string/candidate_item_device_image" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignWithParentIfMissing="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_toEndOf="@+id/item_image"
|
|
||||||
android:layout_toStartOf="@+id/drag_handle"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
android:paddingTop="8dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/item_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:scrollHorizontally="false"
|
|
||||||
android:text="Item Name"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/item_details"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Item Description"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/drag_handle"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:contentDescription="drag handle"
|
|
||||||
android:tint="@color/secondarytext"
|
|
||||||
app:srcCompat="@drawable/ic_drag_handle" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
Loading…
x
Reference in New Issue
Block a user