-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
1,075 additions
and
58 deletions.
There are no files selected for viewing
136 changes: 136 additions & 0 deletions
136
AlbumDialog/src/main/java/com/kongzue/albumdialog/views/PhotoSelectImageView.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package com.kongzue.albumdialog.views; | ||
|
||
import android.content.Context; | ||
import android.content.res.Resources; | ||
import android.graphics.Bitmap; | ||
import android.graphics.BitmapFactory; | ||
import android.graphics.Canvas; | ||
import android.graphics.Color; | ||
import android.graphics.Outline; | ||
import android.graphics.Paint; | ||
import android.graphics.PorterDuff; | ||
import android.graphics.PorterDuffColorFilter; | ||
import android.graphics.Rect; | ||
import android.graphics.RectF; | ||
import android.util.AttributeSet; | ||
import android.view.View; | ||
import android.view.ViewOutlineProvider; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
|
||
import com.kongzue.albumdialog.R; | ||
|
||
public class PhotoSelectImageView extends androidx.appcompat.widget.AppCompatImageView { | ||
|
||
private Bitmap selectFlagBitmap; | ||
private Rect selectFlagRect; | ||
private int borderColor; | ||
private Float borderWidth; | ||
private Paint paint; | ||
|
||
boolean selected; | ||
|
||
public PhotoSelectImageView(@NonNull Context context) { | ||
super(context); | ||
init(); | ||
} | ||
|
||
public PhotoSelectImageView(@NonNull Context context, @Nullable AttributeSet attrs) { | ||
super(context, attrs); | ||
init(); | ||
} | ||
|
||
public PhotoSelectImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | ||
super(context, attrs, defStyleAttr); | ||
init(); | ||
} | ||
|
||
private void init() { | ||
if (paint == null) { | ||
borderColor = getResources().getColor(R.color.albumDefaultThemeDeep); | ||
paint = new Paint(); | ||
paint.setAntiAlias(true); | ||
paint.setColor(borderColor); | ||
paint.setStyle(Paint.Style.STROKE); | ||
paint.setStrokeWidth(getBorderWidth()); | ||
|
||
selectFlagRect = new Rect((int) (getBorderWidth()), (int) (getBorderWidth()), dip2px(30), dip2px(30)); | ||
selectFlagBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.album_dialog_img_selected); | ||
|
||
Bitmap tintedBitmap = Bitmap.createBitmap(selectFlagBitmap.getWidth(), selectFlagBitmap.getHeight(), Bitmap.Config.ARGB_8888); | ||
Canvas canvas = new Canvas(tintedBitmap); | ||
Paint paint = new Paint(); | ||
paint.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.albumDefaultThemeDeep), PorterDuff.Mode.SRC_IN)); | ||
|
||
Paint backgroundPaint = new Paint(); | ||
backgroundPaint.setColor(Color.WHITE); | ||
backgroundPaint.setStyle(Paint.Style.FILL); | ||
canvas.drawCircle(selectFlagBitmap.getWidth() / 2, selectFlagBitmap.getHeight() / 2, selectFlagBitmap.getWidth() / 3, backgroundPaint); | ||
canvas.drawBitmap(selectFlagBitmap, 0, 0, paint); | ||
selectFlagBitmap = tintedBitmap; | ||
} | ||
} | ||
|
||
private float getBorderWidth() { | ||
return borderWidth == null ? dip2px(4) : borderWidth; | ||
} | ||
|
||
@Override | ||
protected void onDraw(Canvas canvas) { | ||
super.onDraw(canvas); | ||
if (selected) { | ||
if (radius == 0) { | ||
canvas.drawRect(0 + getBorderWidth() / 2, 0 + getBorderWidth() / 2, getWidth() - getBorderWidth() / 2, getHeight() - getBorderWidth() / 2, paint); | ||
} else { | ||
RectF rect = new RectF(0 + getBorderWidth() / 2, 0 + getBorderWidth() / 2, getWidth() - getBorderWidth() / 2, getHeight() - getBorderWidth() / 2); | ||
canvas.drawRoundRect(rect, radius, radius, paint); | ||
} | ||
canvas.drawBitmap(selectFlagBitmap, null, selectFlagRect, paint); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean isSelected() { | ||
return selected; | ||
} | ||
|
||
public PhotoSelectImageView setSelectState(boolean selected) { | ||
this.selected = selected; | ||
if (selected) { | ||
setPadding((int) getBorderWidth(), (int) getBorderWidth(), (int) getBorderWidth(), (int) getBorderWidth()); | ||
} else { | ||
setPadding(0, 0, 0, 0); | ||
} | ||
invalidate(); | ||
return this; | ||
} | ||
|
||
private int dip2px(float dpValue) { | ||
return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density); | ||
} | ||
|
||
int radius; | ||
|
||
public void setRadius(int r) { | ||
setOutlineProvider(new ViewOutlineProvider() { | ||
@Override | ||
public void getOutline(View view, Outline outline) { | ||
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), r); | ||
} | ||
}); | ||
setClipToOutline(true); | ||
radius = r; | ||
invalidate(); | ||
} | ||
|
||
public PhotoSelectImageView setBorderColor(int borderColor) { | ||
this.borderColor = borderColor; | ||
return this; | ||
} | ||
|
||
public PhotoSelectImageView setBorderWidth(Float borderWidth) { | ||
this.borderWidth = borderWidth; | ||
return this; | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
AlbumDialog/src/main/java/com/kongzue/albumdialog/views/ScrollableRecycleView.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.kongzue.albumdialog.views; | ||
|
||
import android.content.Context; | ||
import android.util.AttributeSet; | ||
import android.view.MotionEvent; | ||
import android.view.View; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.recyclerview.widget.GridLayoutManager; | ||
import androidx.recyclerview.widget.LinearLayoutManager; | ||
import androidx.recyclerview.widget.RecyclerView; | ||
|
||
import com.kongzue.dialogx.interfaces.ScrollController; | ||
|
||
public class ScrollableRecycleView extends RecyclerView implements ScrollController { | ||
public ScrollableRecycleView(@NonNull Context context) { | ||
super(context); | ||
} | ||
|
||
public ScrollableRecycleView(@NonNull Context context, @Nullable AttributeSet attrs) { | ||
super(context, attrs); | ||
} | ||
|
||
public ScrollableRecycleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | ||
super(context, attrs, defStyleAttr); | ||
} | ||
|
||
/** | ||
* 滑动锁定判断依据,若此标记被置为 true,则意味着滑动由父布局处理,请勿进行任何滚动操作。 | ||
* 具体请参考 {@link #onTouchEvent(MotionEvent)} 的处理方案,其他诸如 ScrollView 处理方式相同。 | ||
*/ | ||
boolean lockScroll; | ||
|
||
@Override | ||
public boolean isLockScroll() { | ||
return lockScroll; | ||
} | ||
|
||
@Override | ||
public void lockScroll(boolean lockScroll) { | ||
this.lockScroll = lockScroll; | ||
} | ||
|
||
@Override | ||
public boolean onTouchEvent(MotionEvent ev) { | ||
if (lockScroll) { | ||
return false; | ||
} | ||
return super.onTouchEvent(ev); | ||
} | ||
|
||
/** | ||
* 是否可以滑动判断依据,若当前滑动布局内容高度小于布局高度则为不可滑动。 | ||
* 此处列举的是 RecycleView 的判断依据编写方法, | ||
* ScrollView 的范例请参考 {@link com.kongzue.dialogx.util.views.BottomDialogScrollView#isCanScroll()} | ||
* | ||
* @return 是否可滑动 | ||
*/ | ||
@Override | ||
public boolean isCanScroll() { | ||
return canScrollVertically(1) || canScrollVertically(-1); | ||
} | ||
|
||
/** | ||
* 此处请给出已滑动距离值,BottomDialog 需要根据此值判断当子布局滑动过程中,父布局是否需要介入滑动流程。 | ||
* 此处列举的是 RecycleView 的判断依据编写方法, | ||
* ScrollView 的范例请参考 {@link com.kongzue.dialogx.util.views.BottomDialogScrollView#getScrollDistance()} | ||
* | ||
* @return 已滑动距离 | ||
*/ | ||
public int getScrollDistance() { | ||
GridLayoutManager layoutManager = (GridLayoutManager) getLayoutManager(); | ||
View firstVisibleItem = this.getChildAt(0); | ||
int firstItemPosition = layoutManager.findFirstVisibleItemPosition(); | ||
int itemHeight = firstVisibleItem.getHeight(); | ||
int firstItemBottom = layoutManager.getDecoratedBottom(firstVisibleItem); | ||
return (firstItemPosition + 1) * itemHeight - firstItemBottom; | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
AlbumDialog/src/main/java/com/kongzue/albumdialog/views/crop/ClipImageBorderView.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package com.kongzue.albumdialog.views.crop; | ||
|
||
import android.content.Context; | ||
import android.graphics.Canvas; | ||
import android.graphics.Color; | ||
import android.graphics.Paint; | ||
import android.util.AttributeSet; | ||
import android.util.TypedValue; | ||
import android.view.View; | ||
|
||
/** | ||
* 中间显示的正方形框 | ||
*/ | ||
public class ClipImageBorderView extends View { | ||
public static int xxx; | ||
public static int yyy; | ||
|
||
public static boolean isshowline = false; | ||
|
||
/** | ||
* 水平方向与View的边距 | ||
*/ | ||
public static int mHorizontalPadding = 0; | ||
/** | ||
* 垂直方向与View的边距 | ||
*/ | ||
public static int mVerticalPadding = 0; | ||
/** | ||
* 绘制的矩形的宽度 | ||
*/ | ||
public static int mWidth = 0; | ||
public static int mHeight = 0; | ||
/** | ||
* 边框的颜色,默认为白色 | ||
*/ | ||
private int mBorderColor = Color.parseColor("#FFFFFF"); | ||
/** | ||
* 边框的宽度 单位dp | ||
*/ | ||
private int mBorderWidth = 1; | ||
|
||
private Paint mPaint; | ||
|
||
public ClipImageBorderView(Context context) { | ||
this(context, null); | ||
} | ||
|
||
public ClipImageBorderView(Context context, AttributeSet attrs) { | ||
this(context, attrs, 0); | ||
} | ||
|
||
public ClipImageBorderView(Context context, AttributeSet attrs, int defStyle) { | ||
super(context, attrs, defStyle); | ||
mBorderWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mBorderWidth, getResources().getDisplayMetrics()); | ||
mPaint = new Paint(); | ||
mPaint.setAntiAlias(true); | ||
} | ||
|
||
@Override | ||
protected void onDraw(Canvas canvas) { | ||
super.onDraw(canvas); | ||
// 计算距离屏幕垂直边界 的边距 | ||
mWidth = getWidth() - 2 * mHorizontalPadding; | ||
mVerticalPadding = (int) ((getHeight() - mWidth * getAspectRatio()) / 2.0); //白描模式矩形高宽比例1.22 | ||
mHeight = getHeight() - mVerticalPadding * 2; | ||
|
||
mPaint.setColor(0xE6ffffff); | ||
mPaint.setStyle(Paint.Style.FILL); | ||
// 绘制左边1,阴影效果 | ||
canvas.drawRect(0, 0, mHorizontalPadding, getHeight(), mPaint); | ||
// 绘制右边2 | ||
canvas.drawRect(getWidth() - mHorizontalPadding, 0, getWidth(), | ||
getHeight(), mPaint); | ||
// 绘制上边3 | ||
canvas.drawRect(mHorizontalPadding, 0, getWidth() - mHorizontalPadding, mVerticalPadding, mPaint); | ||
// 绘制下边4 | ||
canvas.drawRect(mHorizontalPadding, getHeight() - mVerticalPadding, getWidth() - mHorizontalPadding, getHeight(), mPaint); | ||
// 绘制外边框 | ||
mPaint.setColor(mBorderColor); | ||
mPaint.setStrokeWidth(mBorderWidth + 5); | ||
mPaint.setStyle(Paint.Style.STROKE); | ||
canvas.drawRect(mHorizontalPadding, mVerticalPadding, getWidth() - mHorizontalPadding, getHeight() - mVerticalPadding, mPaint); | ||
xxx = getWidth() / 2; | ||
yyy = mVerticalPadding + mWidth / 2; | ||
} | ||
|
||
public void showline(Canvas canvas) { | ||
// 得到网格坐标参数 | ||
float upStart_x1, upStart_y1, upStart_x2, upStart_y2; | ||
float downStart_x1, downStart_y1, downStart_x2, downStart_y2; | ||
float leftStart_x1, leftStart_y1, leftStart_x2, leftStart_y2; | ||
float rightStart_x1, rightStart_y1, rightStart_x2, rightStart_y2; | ||
|
||
//上沿两个点的坐标 | ||
upStart_x1 = mWidth / 3 + mHorizontalPadding; | ||
upStart_y1 = mVerticalPadding; | ||
upStart_x2 = mWidth / 3 * 2 + mHorizontalPadding; | ||
upStart_y2 = mVerticalPadding; | ||
|
||
//下沿两个点的坐标 | ||
downStart_x1 = mWidth / 3 + mHorizontalPadding; | ||
downStart_y1 = getHeight() - mVerticalPadding; | ||
downStart_x2 = mWidth / 3 * 2 + mHorizontalPadding; | ||
downStart_y2 = getHeight() - mVerticalPadding; | ||
|
||
// 左边两个点的坐标 | ||
leftStart_x1 = mHorizontalPadding; | ||
leftStart_y1 = mVerticalPadding + mHeight / 3; | ||
leftStart_x2 = mHorizontalPadding; | ||
leftStart_y2 = mVerticalPadding + mHeight / 3 * 2; | ||
|
||
// 右边两个点的坐标 | ||
rightStart_x1 = mHorizontalPadding + mWidth; | ||
rightStart_y1 = mVerticalPadding + mHeight / 3; | ||
rightStart_x2 = mHorizontalPadding + mWidth; | ||
rightStart_y2 = mVerticalPadding + mHeight / 3 * 2; | ||
|
||
// 绘制网格 | ||
mPaint.setStrokeWidth(mBorderWidth); | ||
canvas.drawLine(upStart_x1, upStart_y1, downStart_x1, downStart_y1, mPaint); | ||
canvas.drawLine(upStart_x2, upStart_y2, downStart_x2, downStart_y2, mPaint); | ||
canvas.drawLine(leftStart_x1, leftStart_y1, rightStart_x1, rightStart_y1, mPaint); | ||
canvas.drawLine(leftStart_x2, leftStart_y2, rightStart_x2, rightStart_y2, mPaint); | ||
} | ||
|
||
public void setHorizontalPadding(int mHorizontalPadding) { | ||
this.mHorizontalPadding = mHorizontalPadding; | ||
} | ||
|
||
public float getAspectRatio() { | ||
return ((ClipView) getParent()).getAspectRatio(); | ||
} | ||
} | ||
|
Oops, something went wrong.