Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hoshi7/adfb6a40bb7a215a344b to your computer and use it in GitHub Desktop.
Save hoshi7/adfb6a40bb7a215a344b to your computer and use it in GitHub Desktop.
穴をひとつ開けられるカスタムビュー
package jp.hoge.app.androidcookpatern.View;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import jp.hoge.app.androidcookpatern.R;
/**
* OneCircleFrontOverlayView
* オーバービューに1カ所、円形のくり抜き箇所を作れるView
*
* @version 1.0
* Created by yusukehoshi on 2014/12/05.
*/
public class OneCircleFrontOverlayView extends View {
Bitmap mImage;
float mCornerRadius = 10f;
int mCircleClipPadding = 5;
int mClipTargetViewId;
int mColor = Color.argb(200,0,0,0);
View mTarget;
public float getCornerRadius() {
return mCornerRadius;
}
public void setCornerRadius(float cornerRadius) {
mCornerRadius = cornerRadius;
}
public OneCircleFrontOverlayView(Context context) {
this(context, null);
}
public void setTargetView(View view){
mTarget = view;
}
public OneCircleFrontOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray tArray =
context.obtainStyledAttributes(
attrs,
R.styleable.OneCircleFrontOverlayView
);
mCornerRadius = (float)tArray.getDimensionPixelSize(R.styleable.OneCircleFrontOverlayView_rectCornerRadius,(int)mCornerRadius);
mClipTargetViewId = tArray.getResourceId(R.styleable.OneCircleFrontOverlayView_circleClipViewId, 0);
mCircleClipPadding = tArray.getDimensionPixelSize(R.styleable.OneCircleFrontOverlayView_circleClipPadding, mCircleClipPadding);
mColor = tArray.getColor(R.styleable.OneCircleFrontOverlayView_overlayColor, mColor);
if(mClipTargetViewId == 0){
return;
}
mTarget = ((Activity)getContext()).findViewById(mClipTargetViewId);
}
@Override
protected void onSizeChanged(int w, int h, int oldW, int oldH){
super.onSizeChanged(w,h,oldW,oldH);
if(mTarget == null){
return;
}
drawOverlay(w, h);
}
private void drawOverlay(int w, int h){
int width = w;
int height = h;
int circleX, circleY = 0;
int circleRadius = 0;
Rect location = getOnWidowLocations(this);
Rect targetLocation = getOnWidowLocations(mTarget);
circleX = targetLocation.left - location.left - mCircleClipPadding;
circleY = targetLocation.top - location.top - mCircleClipPadding;
int across = targetLocation.width() > targetLocation.height() ? targetLocation.width():targetLocation.height();
circleRadius = across / 2 + mCircleClipPadding;
circleX += circleRadius;
circleY += circleRadius;
Bitmap overLay = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(overLay);
Paint paint = new Paint();
paint.setColor(mColor);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
canvas.drawARGB(0, 0, 0, 0);
Path path = new Path();
path.addRoundRect(new RectF(0, 0, width, height), mCornerRadius, mCornerRadius, Path.Direction.CW);
path.addCircle(circleX, circleY, circleRadius, Path.Direction.CCW);
canvas.drawPath(path, paint);
if(mImage != null){
mImage.recycle();
mImage = null;
}
mImage = overLay;
}
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
if(mImage != null) {
canvas.drawBitmap(mImage, 0, 0, new Paint(Paint.ANTI_ALIAS_FLAG));
}
}
@Override
public void onDetachedFromWindow(){
super.onDetachedFromWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(null);
} else {
setBackgroundDrawable(null);
}
destroyDrawingCache();
if(mImage != null){
mImage.recycle();
mImage = null;
}
}
private static Rect getOnWidowLocations(View view){
int[] locations = new int[2];
view.getLocationOnScreen(locations);
return locationToRect(view, locations);
}
private static Rect locationToRect(View view, int[] locations){
Rect rect = new Rect();
rect.set(locations[0], locations[1], locations[0] + view.getWidth(), locations[1] + view.getHeight());
return rect;
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="OneCircleFrontOverlayView">
<attr name="rectCornerRadius" format="dimension" />
<attr name="circleClipPadding" format="dimension" />
<attr name="circleClipViewId" format="reference" />
<attr name="overlayColor" format="color" />
</declare-styleable>
</resources>
package jp.hoge.app.androidcookpatern.Fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import jp.hoge.app.androidcookpatern.R;
public class OverlayHelpViewFragment extends Fragment {
public static OverlayHelpViewFragment newInstance() {
OverlayHelpViewFragment fragment = new OverlayHelpViewFragment();
return fragment;
}
public OverlayHelpViewFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_overlay_help, container, false);
return rootView;
}
}
<?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="match_parent"
android:layout_margin="10dp"
>
<jp.hoge.app.androidcookpatern.View.OneCircleFrontOverlayView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:circleClipPadding="5dp"
app:circleClipViewId="@+id/android_robo"
app:overlayColor="#c800c864"
app:rectCornerRadius="10dp"
/>
<RelativeLayout
android:id="@+id/mark_help_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="こんな感じ!\n\nロボ欲しいよロボ!"
android:textColor="@android:color/white"/>
</RelativeLayout>
</RelativeLayout>
package jp.hoge.app.androidcookpatern;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.ImageView;
import jp.hoge.app.androidcookpatern.Fragment.OverlayHelpViewFragment;
public class OneCircleFrontOverlayActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one_circle_front_overlay);
ImageView robot = (ImageView)findViewById(R.id.android_robo);
robot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OverlayHelpViewFragment overlayHelpViewFragment = OverlayHelpViewFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.overlay_sample_activity,overlayHelpViewFragment);
transaction.commit();
}
});
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#aa9977"
android:id="@+id/overlay_sample_activity"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:background="@android:color/white">
<ImageView
android:id="@+id/android_robo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="100dp"
android:src="@drawable/ic_launcher"/>
</RelativeLayout>
</RelativeLayout>
@kuwako
Copy link

kuwako commented Jun 5, 2016

助かりました!ありがとうございました!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment