Android: Add support in selection image positioning and size-type

This commit is contained in:
Amit Davidi 2017-03-01 09:19:58 +02:00
parent ab311ed19e
commit 1754c12cdd
4 changed files with 108 additions and 13 deletions

View File

@ -5,6 +5,7 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.provider.MediaStore;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -21,12 +22,23 @@ import java.util.concurrent.TimeUnit;
public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.AbsViewHolder> {
public static final int SELECTED_IMAGE_SIZE_NORMAL = SelectableImage.SELECTED_IMAGE_NORMAL_SIZE_DP;
public static final int SELECTED_IMAGE_SIZE_LARGE = SelectableImage.SELECTED_IMAGE_LARGE_SIZE_DP;
private static final int[] selectedPositionTypeToGravity = new int[] {
Gravity.TOP | Gravity.RIGHT,
Gravity.TOP | Gravity.LEFT,
Gravity.BOTTOM | Gravity.RIGHT,
Gravity.BOTTOM | Gravity.LEFT,
Gravity.CENTER
};
private static final String DEFAULT_CUSTOM_BUTTON_BACKGROUND_COLOR = "#f2f4f5";
private static int VIEW_TYPE_IMAGE = 0;
private static int VIEW_TYPE_TAKE_PICTURE = 1;
public static final String[] PROJECTION = new String[]{
private static final String[] PROJECTION = new String[]{
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.MIME_TYPE
@ -145,8 +157,10 @@ public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.AbsViewH
private ArrayList<String> supportedFileTypes = new ArrayList<>();
private String albumName = "";
private Drawable selectedDrawable;
private Drawable unselectedDrawable;
private Drawable customButtonImage;
private Integer selectedDrawableGravity;
private Integer selectedDrawableSize;
private Drawable unselectedDrawable;
private String customButtonBackgroundColor = DEFAULT_CUSTOM_BUTTON_BACKGROUND_COLOR;
private ArrayList<Image> images = new ArrayList<>();
@ -182,6 +196,14 @@ public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.AbsViewH
this.unselectedDrawable = unselectedDrawable;
}
public void setSelectionDrawablePosition(int positionType) {
this.selectedDrawableGravity = selectedPositionTypeToGravity[positionType];
}
public void setSelectedDrawableSize(int selectedDrawableSize) {
this.selectedDrawableSize = selectedDrawableSize;
}
public void setSupportedFileTypes(ArrayList<String> supportedFileTypes) {
this.supportedFileTypes = supportedFileTypes;
}
@ -284,7 +306,7 @@ public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.AbsViewH
@Override
public AbsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_IMAGE) {
SelectableImage v = new SelectableImage(view.getContext());
SelectableImage v = new SelectableImage(view.getContext(), selectedDrawableGravity, selectedDrawableSize);
v.setScaleType(ImageView.ScaleType.CENTER_CROP);
v.setBackgroundColor(Color.LTGRAY);
return new ImageHolder(v);

View File

@ -29,8 +29,10 @@ public class GalleryViewManager extends SimpleViewManager<GalleryView> {
private final String UNSUPPORTED_OVERLAY_KEY = "unsupportedOverlayColor";
private final String CUSTOM_BUTTON_IMAGE_KEY = "image";
private final String CUSTOM_BUTTON_BCK_COLOR_KEY = "backgroundColor";
private ThemedReactContext reactContext;
private final String SELECTION_SELECTED_IMAGE_KEY = "selectedImage";
private final String SELECTION_UNSELECTED_IMAGE_KEY = "unselectedImage";
private final String SELECTION_POSITION_KEY = "position";
private final String SELECTION_SIZE_KEY = "size";
/**
* A handler is required in order to sync configurations made to the adapter - some must run off the UI thread (e.g. drawables
@ -49,8 +51,6 @@ public class GalleryViewManager extends SimpleViewManager<GalleryView> {
@Override
protected GalleryView createViewInstance(ThemedReactContext reactContext) {
this.reactContext = reactContext;
final HandlerThread handlerThread = new HandlerThread("GalleryViewManager.configThread");
handlerThread.start();
adapterConfigHandler = new Handler(handlerThread.getLooper());
@ -68,6 +68,7 @@ public class GalleryViewManager extends SimpleViewManager<GalleryView> {
getViewAdapter(view).refreshData();
}
});
super.onAfterUpdateTransaction(view);
}
@ReactProp(name = "minimumInteritemSpacing")
@ -137,6 +138,39 @@ public class GalleryViewManager extends SimpleViewManager<GalleryView> {
});
}
@ReactProp(name = "selection")
public void setSelectionProperties(final GalleryView view, final ReadableMap selectionProps) {
final String selectedImage = getStringSafe(selectionProps, SELECTION_SELECTED_IMAGE_KEY);
final String unselectedImage = getStringSafe(selectionProps, SELECTION_UNSELECTED_IMAGE_KEY);
final Integer position = getIntSafe(selectionProps, SELECTION_POSITION_KEY);
final String size = getStringSafe(selectionProps, SELECTION_SIZE_KEY);
dispatchOnConfigJobQueue(new Runnable() {
@Override
public void run() {
final GalleryAdapter viewAdapter = getViewAdapter(view);
if (selectedImage != null) {
final Drawable selectedDrawable = ResourceDrawableIdHelper.getIcon(view.getContext(), selectedImage);
viewAdapter.setSelectedDrawable(selectedDrawable);
}
if (unselectedImage != null) {
final Drawable unselectedDrawable = ResourceDrawableIdHelper.getIcon(view.getContext(), unselectedImage);
viewAdapter.setUnselectedDrawable(unselectedDrawable);
}
if (position != null) {
viewAdapter.setSelectionDrawablePosition(position);
}
if (size != null) {
final int sizeCode = size.equalsIgnoreCase("large") ? GalleryAdapter.SELECTED_IMAGE_SIZE_LARGE : GalleryAdapter.SELECTED_IMAGE_SIZE_NORMAL;
viewAdapter.setSelectedDrawableSize(sizeCode);
}
}
});
}
@ReactProp(name = "fileTypeSupport")
public void setFileTypeSupport(final GalleryView view, final ReadableMap fileTypeSupport) {
final ReadableArray supportedFileTypes = fileTypeSupport.getArray(SUPPORTED_TYPES_KEY);
@ -221,6 +255,13 @@ public class GalleryViewManager extends SimpleViewManager<GalleryView> {
return null;
}
private @Nullable Integer getIntSafe(ReadableMap map, String key) {
if (map.hasKey(key)) {
return map.getInt(key);
}
return null;
}
private @NonNull ArrayList<String> readableArrayToList(ReadableArray uris) {
ArrayList<String> list = new ArrayList<>();
for(int i = 0; i < uris.size(); i++) {

View File

@ -24,7 +24,11 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
public class SelectableImage extends FrameLayout {
private static final int MINI_THUMB_HEIGHT = 512;
private static final int MINI_THUMB_WIDTH = 384;
public static final int MAX_SAMPLE_SIZE = 8;
private static final int MAX_SAMPLE_SIZE = 8;
private static final int DEFAULT_SELECTED_IMAGE_GRAVITY = Gravity.TOP | Gravity.RIGHT;
public static final int SELECTED_IMAGE_NORMAL_SIZE_DP = 22;
public static final int SELECTED_IMAGE_LARGE_SIZE_DP = 36;
private final ImageView imageView;
private final ImageView selectedView;
@ -38,17 +42,16 @@ public class SelectableImage extends FrameLayout {
private boolean selected;
private int inSampleSize;
public SelectableImage(Context context) {
public SelectableImage(Context context, Integer selectedImageGravity, Integer selectedImageSize) {
super(context);
setPadding(1, 1, 1, 1);
setBackgroundColor(0xedeff0);
imageView = new ImageView(context);
addView(imageView, MATCH_PARENT, MATCH_PARENT);
selectedView = new ImageView(context);
int dp22 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 22, context.getResources().getDisplayMetrics());
LayoutParams params = new FrameLayout.LayoutParams(dp22, dp22, Gravity.TOP | Gravity.RIGHT);
params.setMargins(30, 30, 30, 30);
addView(selectedView, params);
addView(selectedView, createSelectedImageParams(selectedImageGravity, selectedImageSize));
createUnsupportedView();
}
@ -176,4 +179,15 @@ public class SelectableImage extends FrameLayout {
return inSampleSize;
}
private LayoutParams createSelectedImageParams(Integer gravity, Integer sizeDp) {
gravity = gravity != null ? gravity : DEFAULT_SELECTED_IMAGE_GRAVITY;
sizeDp = sizeDp != null ? sizeDp : SELECTED_IMAGE_NORMAL_SIZE_DP;
final int sizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sizeDp, getResources().getDisplayMetrics());
final LayoutParams params = new FrameLayout.LayoutParams(sizePx, sizePx, gravity);
params.setMargins(30, 30, 30, 30);
return params;
}
}

View File

@ -38,6 +38,13 @@ export default class CameraKitGalleryView extends Component {
if (transformedProps.selectedImageIcon) {
transformedProps.selectedImageIcon = resolveAssetSource(transformedProps.selectedImageIcon).uri;
}
if (_.get(transformedProps, 'selection.selectedImage')) {
_.update(transformedProps, 'selection.selectedImage', (image) => resolveAssetSource(image).uri);
}
if (_.get(transformedProps, 'selection.position')) {
const position = this.transformSelectedImagePosition(_.get(transformedProps, 'selection.position'));
_.update(transformedProps, 'selection.position', (pos) => position);
}
return <GalleryView {...transformedProps} onTapImage={this.onTapImage}/>
}
@ -46,4 +53,15 @@ export default class CameraKitGalleryView extends Component {
this.props.onTapImage(event);
}
}
transformSelectedImagePosition(position) {
switch (position) {
case 'top-right': return 0;
case 'top-left': return 1;
case 'bottom-right': return 2;
case 'bottom-left': return 3;
case 'center': return 4;
default: return null;
}
}
}