当前位置:网站首页>Arc view and arc viewpager
Arc view and arc viewpager
2022-06-29 10:17:00 【Mr beast no beast】
Inspired by :Android Project summary ( One ): arc ViewPager And arc HeaderView
The picture is also from the link above .

I have seen many such effects recently , Colleagues around me have also mentioned this kind of arc View, In fact, there are many ways to achieve this effect , I also tried to realize , Although the way is not very good , But at least it works .
1 Ideas
The first reaction to this effect is to use Bezier curve to draw a closed curve with an arc below , Then call Paint Of setXfermode() Set it to SRC_IN( There are many articles about this on the Internet , This pattern is to take the intersection of two things , Show the meaning of the upper image ), And then draw pictures , Um. , That's what I did when I got the round head , In theory, it's completely ojbk
2 ArcView
Do as you say , Customize one first ArcView:
public class ArcView extends android.support.v7.widget.AppCompatImageView {
private Paint mPaint;
private Path mPath; // The following is the closed curve of arc
private Bitmap mBitmap; // picture
private int width; // Control width
private int height; // Control high
private int arcWidth; // Arc width
private int arcHeight; // Arc height
private Rect srcRect; // Picture drawing area
private Rect dstRect; // Picture display area
public ArcView(Context context) {
this(context, null);
}
public ArcView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
width = context.getResources().getDisplayMetrics().widthPixels;
height = context.getResources().getDisplayMetrics().heightPixels / 2;
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE); // The brush is set to fill , Don't forget
mPaint.setAntiAlias(true);
mPath = new Path();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = getContext().getResources().getDisplayMetrics().widthPixels;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
height = getContext().getResources().getDisplayMetrics().heightPixels / 2;
}
arcWidth = width;
arcHeight = height / 5; // Take the height of the arc as one fifth of the whole control
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
mPath.moveTo(0, 0);
mPath.moveTo(0, height - arcHeight);
mPath.quadTo(width / 2, height + arcHeight, width, height - arcHeight);
mPath.lineTo(width, 0);
mPath.lineTo(0, 0);
canvas.drawPath(mPath, mPaint);
if (mBitmap != null) {
srcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()); // Draw area
dstRect = new Rect(0, 0, width, height); // Display area
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mBitmap, srcRect, dstRect, mPaint);
}
}
@Override
public void setImageBitmap(Bitmap bitmap) {
this.mBitmap = bitmap;
invalidate();
}
@Override
public void setImageResource(int resourceId) {
this.mBitmap = BitmapFactory.decodeResource(getContext().getResources(), resourceId);
invalidate();
}
/**
* Description: Get the picture after loading
* Date:2018/1/22
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getDrawable() != null) {
mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
}
}
}I write the code in one breath , Write all the way down with clear mind , Without hindrance , The layout is very simple :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.qinshou.arcdemo.activity.ArcViewActivity">
<com.qinshou.arcdemo.widget.ArcView
android:layout_width="wrap_content"
android:src="@drawable/a"
android:id="@+id/av_test"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>Run up and look at it hopefully :

WTF,why! Is there something wrong with this line of code ?
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));But I used to draw round pictures like this , There are no flaws , I put drawPath() Switch to drawCircle() Still so , Um. , There must be some secret in it , When I settle down, I will dissect it carefully , The top priority is to achieve the arc effect .All the roads to the Rome, The arc is shown below , Do you want to draw pictures first , Draw another white arc View To cover the bottom half of it ? That is, a white one View:

Um. , Have a try , hold onDraw() Change the method :
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
srcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
dstRect = new Rect(0, 0, width, height);
canvas.drawBitmap(mBitmap, srcRect, dstRect, mPaint);
}
mPath.moveTo(0, height - arcHeight);
mPath.quadTo(width / 2, height + arcHeight, width, height - arcHeight);
mPath.lineTo(width, height);
mPath.lineTo(0, height);
canvas.drawPath(mPath, mPaint);
}
Although this method has the suspicion of opportunism , But it's also a way of thinking , Wait for the younger brother to find out setXfermode() The method is not easy to use. When who is causing trouble , And then catch it to plead guilty .
3 ArcViewPager
public class ArcViewPagerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_arc_view_pager);
ViewPager viewPager = (ViewPager) findViewById(R.id.vp_test);
int[] resource = new int[]{R.drawable.a, R.drawable.b, R.drawable.c
, R.drawable.d, R.drawable.e, R.drawable.f};
List<View> viewList = new ArrayList<>();
for (int i = 0; i < resource.length; i++) {
ArcView mArcView = new ArcView(this);
mArcView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mArcView.setImageResource(resource[i]);
viewList.add(mArcView);
}
viewPager.setAdapter(new MyViewPagerAdapter(viewList));
}
private class MyViewPagerAdapter extends PagerAdapter {
private List<View> viewList = new ArrayList<>();
public MyViewPagerAdapter(List<View> viewList) {
this.viewList = viewList;
}
@Override
public int getCount() {
return viewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(viewList.get(position));
return viewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(viewList.get(position));
}
}
}
public class ArcViewPager extends RelativeLayout {
private ViewPager mViewPager;
public ArcViewPager(Context context) {
this(context, null);
}
public ArcViewPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
ArcCoverView mArcCoverView = new ArcCoverView(getContext());
mArcCoverView.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 200));
mViewPager = new ViewPager(getContext()); // establish ViewPager
addView(mViewPager); // add to ViewPager
addView(mArcCoverView); // Add arc occlusion View
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
// Ergodic View, Mask the arc View Placed on the bottom
for (int i = 0; i < getChildCount(); i++) {
if (getChildAt(i) instanceof ArcCoverView) {
ArcCoverView arcCoverView = (ArcCoverView) getChildAt(i);
arcCoverView.layout(0, getMeasuredHeight() - arcCoverView.getMeasuredHeight(), arcCoverView.getMeasuredWidth(), getMeasuredHeight());
}
}
}
/**
* Description: Set the adapter to ViewPager
* Date:2018/1/22
*/
public void setAdapter(PagerAdapter adapter) {
mViewPager.setAdapter(adapter);
}
/**
* Description: Arc occlusion View
* Date:2018/1/22
*/
public class ArcCoverView extends View {
private Paint mPaint;
private Path mPath;
private int width;
private int height;
public ArcCoverView(Context context) {
this(context, null);
}
public ArcCoverView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcCoverView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
width = context.getResources().getDisplayMetrics().widthPixels;
height = 200;
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setAntiAlias(true);
mPath = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.moveTo(0, 0);
mPath.quadTo(width / 2, height * 2, width, 0);
mPath.lineTo(width, height);
mPath.lineTo(0, height);
canvas.drawPath(mPath, mPaint);
}
}
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_arc_view_pager);
ArcViewPager arcViewPager = (ArcViewPager) findViewById(R.id.avp_test);
int[] resource = new int[]{R.drawable.a, R.drawable.b, R.drawable.c
, R.drawable.d, R.drawable.e, R.drawable.f};
List<View> viewList = new ArrayList<>();
for (int i = 0; i < resource.length; i++) {
ImageView mImageView = new ImageView(this);
mImageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
mImageView.setImageResource(resource[i]);
viewList.add(mImageView);
}
arcViewPager.setAdapter(new MyViewPagerAdapter(viewList));
}
4 summary
边栏推荐
- 1099 build a binary search tree (30 points)
- Nacos environmental isolation
- 蛇形填数
- Is flush stock trading software reliable and safe?
- Rikka with Cake(线段树+线段树)
- Signal works: time varying and time invariant
- RecyclerView 粘性(悬浮)头部
- Substring score - Ultra detailed version - the last programming challenge
- 2019.10.27训练总结
- Pointer functions and function pointers
猜你喜欢

Ce projet Open source est super wow, des photos manuscrites sont générées en ligne

另类实现 ScrollView 下拉头部放大

Judgment of points inside and outside polygon

时变和非时变

Codeforces Round #645 (Div. 2)

EDA与VHDL题库

Nacos环境隔离

This open source project is super wow, and handwritten photos are generated Online

Pipeline details of IPC (interprocess communication)

RecyclerView 通用适配器封装
随机推荐
HDU 6778 Car (分组枚举-->状压 dp)
1146 Topological Order (25 分)
Community Union
2019.10.23训练总结
SymPy Tutorial(译)
Pointer functions and function pointers
nacos注册中心集群
FreeRTOS (VIII) - time management
六度空间 bfs
The Stones Game【取石子博弈 & 思维】
Force deduction 85 question maximum rectangle
Image of the basic component of the shutter
acwing271【杨老师的照相排列】【线性DP】
FreeRTOS (IX) - queue
container
Nacos环境隔离
SeaweedFS安全配置(Security Configuration)
If I were in Beijing, where would it be better to open an account? In addition, is it safe to open an account online now?
Ce projet Open source est super wow, des photos manuscrites sont générées en ligne
Judgment of points inside and outside polygon