首先穿件一个ReportBaseCell
package com.ankoninc.esdiagnose.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.ankoninc.esdiagnose.R;
public class ReportBaseCell extends LinearLayout {
private TextView mTitleView;
private WrappedButton mButton;
private String mTitle;
public ReportBaseCell(Context context) {
this(context, null);
}
public ReportBaseCell(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ReportBaseCell(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ReportCellItem);
if (a != null) {
mTitle = a.getString(R.styleable.ReportCellItem_reportTitleText);
a.recycle();
}
setupViews(context);
}
private void setupViews(Context context) {
setOrientation(VERTICAL);
View titleContainer = inflate(context, R.layout.report_cell_title, this);
mTitleView = (TextView) titleContainer.findViewById(R.id.title);
mTitleView.setText(mTitle);
mButton = (WrappedButton) titleContainer.findViewById(R.id.button);
}
public void setTitle(int resId) {
mTitleView.setText(resId);
}
public void setTitle(String text) {
mTitleView.setText(text);
}
public void setButtonText(int resId) {
mButton.setText(resId);
}
public void setButtonText(String text) {
mButton.setText(text);
}
public void setButtonClickListener(OnClickListener listener) {
mButton.setOnClickListener(listener);
}
public void setButtonVisibility(boolean visible) {
mButton.setVisibility(visible ? VISIBLE : GONE);
}
}
第二步:package com.ankoninc.esdiagnose.view;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import com.ankoninc.data.MedicalExamination;
import com.ankoninc.esdiagnose.R;
import com.ankoninc.esdiagnose.report.DragManager;
import com.ankoninc.esdiagnose.report.DragState;
import com.ankoninc.esdiagnose.report.ReportImageAdapter;
import com.ankoninc.imageview.model.DownloadResult;
import com.ankoninc.imageview.model.ImageDiagnoseItem;
import com.ankoninc.utils.Log;
import java.util.List;
/**
* 报告图片的,item之间可移动交换
* Created by zengna on 2016/6/8.
*/
public class ReportImageCell extends ReportBaseCell implements RecyclerView.OnItemTouchListener, ReportImageAdapter.ImageDragListener {
private static final String LOG_TAG = "ReportImageCell";
private TextView mNotifyView;
private RecyclerView mImageContainer;
private ReportImageAdapter mAdapter;
private GridLayoutManager mLayoutManager;
private DragManager dragManager;
private final PointF dragTouchPoint = new PointF();
private MedicalExamination mPatientExamination;
private DownloadResult mDownloadResult;
private ImageListener mImageListener;
private GestureDetector mGestureDetector;
public ReportImageCell(Context context) {
this(context, null);
}
public ReportImageCell(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ReportImageCell(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupViews(context);
init(context);
}
private void setupViews(Context context) {
setTitle(R.string.report_examination_image);
setButtonText(R.string.finish);
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mAdapter.switchMode(false);
}
});
setButtonVisibility(false);
View view = inflate(context, R.layout.report_image_cell, this);
mNotifyView = (TextView) view.findViewById(R.id.image_diagnose_notify);
mImageContainer = (RecyclerView) view.findViewById(R.id.report_image_container);
}
private void init(Context context) {
updateNotify();
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
Log.d(LOG_TAG, "onDown");
View itemView = mImageContainer.findChildViewUnder(e.getX(),e.getY());
return super.onDown(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.d(LOG_TAG, "onSingleTapConfirmed");
onItemTouched(mImageContainer, e);
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.d(LOG_TAG, "onDoubleTap");
onItemTouched(mImageContainer, e);
return super.onDoubleTap(e);
}
@Override
public void onLongPress(MotionEvent e) {
Log.d(LOG_TAG, "onLongPress");
super.onLongPress(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return super.onScroll(e1, e2, distanceX, distanceY);
}
});
mAdapter = new ReportImageAdapter(this, mPatientExamination, mDownloadResult,this);
mLayoutManager = new GridLayoutManager(context, 2, VERTICAL, false);
mImageContainer.setLayoutManager(mLayoutManager);
mImageContainer.setAdapter(mAdapter);
mImageContainer.addOnItemTouchListener(this);
dragManager = new DragManager(mImageContainer, mAdapter);
dragManager.setCanDrag(true);
mImageContainer.setOnDragListener(dragManager);
}
public void updateNotify() {
//捕获图片数量
int capturedImagesCount = 0;
//选中图片的数量
int selectedImagesCount = 0;
if (mDownloadResult != null) {
List<ImageDiagnoseItem> items = mDownloadResult.findCapturedItems();
if (items != null) {
capturedImagesCount = items.size();
List<ImageDiagnoseItem> selectedImages = DownloadResult.findSelectedImages(items);
selectedImagesCount = selectedImages == null ? 0 : selectedImages.size();
}
}
if (selectedImagesCount > 0) {
mNotifyView.setText(getContext().getString(R.string.report_diagnose_notify_text, capturedImagesCount, selectedImagesCount));
} else {
mNotifyView.setText(R.string.report_cannot_upload_notify);
}
if (mImageListener != null) {
mImageListener.onCountChanged(capturedImagesCount, selectedImagesCount);
}
}
public void setDownloadResult(MedicalExamination examination, DownloadResult result) {
mDownloadResult = result;
mPatientExamination = examination;
mAdapter.resetList(examination, result);
updateNotify();
}
public void refreshDownload(int startIndex, int endIndex) {
mAdapter.refreshDownload(startIndex, endIndex);
}
public void notifyItemChanged(ImageDiagnoseItem item) {
mAdapter.notifyItemChanged(item);
}
public void startSelectImage() {
if (mImageListener != null) {
mImageListener.requestSelectImage();
}
}
public void startEditImage(ImageDiagnoseItem item) {
if (mImageListener != null) {
mImageListener.requestShowEditDialog(item);
}
}
public void setImageListener(ImageListener listener) {
mImageListener = listener;
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
dragTouchPoint.set(e.getX(), e.getY());
return false;
}
public List<ImageDiagnoseItem> getOrderedSelectedImages() {
return mAdapter.getOrderedSelectedImages();
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
private void onItemTouched(RecyclerView rv, MotionEvent e) {
View itemView = rv.findChildViewUnder(e.getX(), e.getY());
Log.d(LOG_TAG, "onItemTouched itemView: %s", itemView);
if (itemView != null) {
int position = rv.getChildAdapterPosition(itemView);
mAdapter.onItemClicked(position);
}
}
@Override
public void onStartDrag(View view, ImageDiagnoseItem item) {
if (mImageListener != null && mImageListener.allowDrag()) {
DragState dragState = new DragState(item, item.getIndex());
DragShadowBuilder dragShadowBuilder = new com.ankoninc.esdiagnose.report.DragShadowBuilder(view,
new Point(((int) (dragTouchPoint.x - view.getX())), (int) (dragTouchPoint.y - view.getY())));
Point shadowSize = new Point();
Point shadowTouchPoint = new Point();
dragShadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
view.startDrag(null, dragShadowBuilder, dragState, 0);
}
}
public interface ImageListener {
boolean allowDrag();
void onCountChanged(int capturedImagesCount, int selectedImagesCount);
void requestSelectImage();
void requestShowEditDialog(ImageDiagnoseItem item);
}
}
3、创建adapter
package com.ankoninc.esdiagnose.report;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.ankoninc.data.ADVData;
import com.ankoninc.data.MedicalExamination;
import com.ankoninc.esdiagnose.AppContext;
import com.ankoninc.esdiagnose.R;
import com.ankoninc.esdiagnose.view.ReportImageCell;
import com.ankoninc.imageview.DragImageView;
import com.ankoninc.imageview.model.DownloadResult;
import com.ankoninc.imageview.model.ImageDiagnoseItem;
import com.ankoninc.utils.Log;
import java.util.List;
/**
* Created by zengna on 2016/6/8.
*/
public class ReportImageAdapter extends RecyclerView.Adapter<ReportImageAdapter.ImageViewHolder> implements DragListener{
private static final String LOG_TAG = "ReportImageAdapter";
private static final int TYPE_DEFAULT = 0;
private static final int TYPE_ADD = 1;
private static final int TYPE_DELETE = 2;
private Context mContext;
private ReportImageCell mTargetView;
private MedicalExamination mPatientExamination;
private boolean mEditMode;
private List<ImageDiagnoseItem> mList;
private Bitmap mLoadingBitmap;
private ImageDragListener mListener;
private int dragItemId = DragListener.NO_ID;
public ReportImageAdapter(ReportImageCell targetView, MedicalExamination examination,
DownloadResult downloadResult, ImageDragListener listener) {
mContext = targetView.getContext();
mTargetView = targetView;
mListener = listener;
resetList(examination, downloadResult);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
mLoadingBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.loading, options);
}
public void resetList(MedicalExamination examination, DownloadResult downloadResult) {
mPatientExamination = examination;
if (downloadResult != null) {
mList = downloadResult.getOrderedSelectedImagesByRemarks();
}
notifyDataSetChanged();
}
/**
* 更新是否下载的标志
* @param startIndex
* @param endIndex
*/
public void refreshDownload(int startIndex, int endIndex) {
int count = getItemCount() - 2;
if (count <= 0) {
return;
}
// 因为有前后方向,所以重新定义start,end
int start = Math.min(startIndex, endIndex);
int end = Math.max(startIndex, endIndex);
int validStart = Math.max(0, start);
int validEnd = Math.min(end, count - 1);
for (int i=validStart; i<=validEnd; i++) {
ImageDiagnoseItem item = getItem(i);
if (item == null) {
continue;
}
item.setDownloaded(true);
notifyItemChanged(i);
}
}
public boolean isEditMode() {
return mEditMode;
}
public void switchMode(boolean editMode) {
if (editMode == mEditMode) {
return;
}
mEditMode = editMode;
notifyDataSetChanged();
mTargetView.setButtonVisibility(editMode);
}
private void startSelectImage() {
mTargetView.startSelectImage();
}
private void startEditImage(int position) {
ImageDiagnoseItem item = getItem(position);
if (item == null || !item.isDownloaded()) {
return;
}
mTargetView.startEditImage(item);
}
public boolean onItemClicked(int position) {
if (position < 0 || position >= getItemCount()) {
return false;
}
int viewType = getItemViewType(position);
switch (viewType) {
case TYPE_ADD:
if (mEditMode) {
switchMode(false);
} else {
startSelectImage();
}
break;
case TYPE_DELETE:
switchMode(!mEditMode);
break;
case TYPE_DEFAULT:
default:
if (mEditMode) {
remove(position);
} else {
startEditImage(position);
}
break;
}
return true;
}
public void notifyItemChanged(ImageDiagnoseItem item) {
if (mList == null || mList.isEmpty()) {
return;
}
int position = mList.indexOf(item);
if (position == -1) {
return;
}
notifyItemChanged(position);
}
/**
*
* @return
*/
public List<ImageDiagnoseItem> getOrderedSelectedImages() {
return mList;
}
@Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.report_image_item, parent, false);
return new ImageViewHolder(view, new ImageViewHolder.OnLongClickListener() {
@Override
public void onLongClick(View view, int position) {
ImageDiagnoseItem item = getItem(position);
if (getItemViewType(position) == TYPE_DEFAULT && item != null) {
mListener.onStartDrag(view, item);
}
}
});
}
@Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
int viewType = getItemViewType(position);
ImageDiagnoseItem item = getItem(position);
Bitmap bitmap = null;
if (item != null && item.isDownloaded()) {
String patientName = mPatientExamination.getPatientName();
ADVData.ImageInfo imageInfo = ADVData.getImageAt(mPatientExamination.getRecordUid(),
patientName, item.getFileNo(), item.getOffset());
if (imageInfo != null && imageInfo.image != null) {
bitmap = DragImageView.drawMarkImage(imageInfo.image, item.getPointInfos());
}
}
holder.bind(bitmap == null ? mLoadingBitmap : bitmap, mEditMode, viewType);
}
@Override
public int getItemViewType(int position) {
int count = getItemCount();
if (position == count-1) {
return TYPE_DELETE;
} else if (position == count-2) {
return TYPE_ADD;
} else {
return TYPE_DEFAULT;
}
}
@Override
public int getItemCount() {
int count = mList == null ? 0 : mList.size();
return count + 2;
}
public ImageDiagnoseItem getItem(int position) {
if (position >=0 && position < mList.size()) {
return mList.get(position);
}
return null;
}
/**
* 删除某张图片
* @param position
*/
public boolean remove(int position) {
ImageDiagnoseItem item = getItem(position);
if (item != null) {
item.setSelected(false);
item.setImageOrder(0);
mList.remove(position);
mTargetView.updateNotify();
notifyItemRemoved(position);
return true;
}
return false;
}
@Override
public boolean onMoveItem(int fromPosition, int toPosition) {
if (getItemViewType(toPosition) != TYPE_DEFAULT
&& getItemViewType(fromPosition) != getItemViewType(toPosition)) {
return false;
}
mList.add(toPosition, mList.remove(fromPosition));
notifyItemMoved(fromPosition, toPosition);
return true;
}
@Override
public void notifyItemChange(int position, int dragItemId) {
this.dragItemId = dragItemId;
notifyItemChanged(position);
}
@Override
public int getPosition(Object object) {
return mList.indexOf(object);
}
@Override
public void onDragEnd(int position) {
}
static class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener{
private View mImageContainer;
private ImageView mImage;
private ImageView mDeleteButton;
private OnLongClickListener mListener;
public ImageViewHolder(View view, OnLongClickListener listener) {
super(view);
mImageContainer = view.findViewById(R.id.container);
mImage = (ImageView) view.findViewById(R.id.image);
mDeleteButton = (ImageView) view.findViewById(R.id.delete);
mListener = listener;
this.itemView.setOnLongClickListener(this);
}
public void bind(final Bitmap bitmap, final boolean editMode, final int viewType) {
switch (viewType) {
case TYPE_ADD:
bindAddButton(editMode);
break;
case TYPE_DELETE:
bindDeleteButton(editMode);
break;
default:
bindImage(bitmap, editMode);
}
}
private void bindImage(final Bitmap bitmap, final boolean editMode) {
mImage.setImageBitmap(bitmap);
mDeleteButton.setVisibility(editMode ? View.VISIBLE : View.INVISIBLE);
mImageContainer.setBackground(AppContext.getInstance().getResources().getDrawable(R.drawable.report_image_background));
}
private void bindAddButton(final boolean editMode) {
mDeleteButton.setVisibility(View.GONE);
mImage.setImageResource(R.drawable.report_image_add);
mImageContainer.setBackground(AppContext.getInstance().getResources().getDrawable(R.drawable.report_image_button_background));
itemView.setVisibility(editMode ? View.INVISIBLE : View.VISIBLE);
}
private void bindDeleteButton(final boolean editMode) {
mDeleteButton.setVisibility(View.GONE);
mImage.setImageResource(R.drawable.report_image_delete);
mImageContainer.setBackground(AppContext.getInstance().getResources().getDrawable(R.drawable.report_image_button_background));
itemView.setVisibility(editMode ? View.INVISIBLE : View.VISIBLE);
}
@Override
public boolean onLongClick(View v) {
Log.d("ImageViewHolder", "onLongClick");
mListener.onLongClick(v, getAdapterPosition());
return true;
}
interface OnLongClickListener {
void onLongClick(View view, int position);
}
}
public interface ImageDragListener {
void onStartDrag(View view, ImageDiagnoseItem item);
}
}