I.はじめに
最近のプロジェクトのために一日中インターネットで見つけ、3日以内に完了定義すると、サーチ機能を開発する緊急の必要性を必要と、達成するための様々な方法を試し、実際には、キャンバスの元絵に描かれた使用BitmapShaderとShapeDrawableほかなら、存在しない、いくつかのこうしたクリップ関連のcanavas方法などの他の言語の方法、が、私はプロジェクトのニーズを満たすことができません。効果がサーチライトを実現することができるが、第一の方法は、欠点は、元画像が存在しなければならないということである、と私はプロジェクトの要件あなたがインターフェイスであるにかかわらず、バックグラウンド(サーチライトの部分が透明になってされているのと同等のプローブを直接照らすことができなければなりませんを持っています直接)背中を参照してください。最後に、私は次の日は、実行可能な解決策を考え出すので、以下のように、自分自身を達成するための方法を考えることができます。
第二に、アイデア
次のような要件によると、要約されています:
-サーチ機能
-可動サーチ
-の部分的に透明サーチ
さらに他のアプリケーションインターフェースで使用-
第三に、達成するために
直接コードでADO、:
-1透明活性を達成
<style name="TranspantTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
今後の、設定ファイル内の上記のテーマアクティビティーに追加
android:theme="@style/theApp"
読みます:
android:theme="@style/TranspantTheme"
このような活動は、起動透明です。
-2。(アプリケーションインタフェースは、他に依然として利用可能である)アプリケーションがまだ利用可能で終了
使用ウィンドウマネージャ:
private WindowManager windowManager;
private WindowManager.LayoutParams wmParams,wm;
private int wmType;
private void initView() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
wmType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
wmType = WindowManager.LayoutParams.TYPE_PHONE;
}
windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
wmParams = new WindowManager.LayoutParams();
wmParams.type = wmType;
wmParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.gravity = Gravity.LEFT | Gravity.TOP;
wmParams.x = 0;
wmParams.y = 0;
wmParams.width = WindowManager.LayoutParams.MATCH_PARENT;
wmParams.height = WindowManager.LayoutParams.MATCH_PARENT;
wmParams.format = PixelFormat.RGBA_8888;
wm = new WindowManager.LayoutParams();
wm.type = wmType;
wm.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
wm.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wm.gravity = Gravity.RIGHT | Gravity.TOP;
wm.x = 0;
wm.y = 0;
wm.width = 100;
wm.height = 100;
wm.format = PixelFormat.RGBA_8888;
}
初期化良いウィンドウマネージャは、コンフィギュレーションファイルにアクティビティを横画面表示(ウィンドウマネージャの影響を受ける)を設定することを忘れないでください
-3。サーチライトは、定義された関数の表示を実現します
直接コードに:
public class MyImageView extends android.support.v7.widget.AppCompatImageView{
private Paint paint1,paint2;//两只笔
private float x=200,y=200;
private int screenWidth,screenHeight;
public MyImageView(Context context) {
super(context);
initData();
}
private synchronized void initData() {
//获取屏幕宽高
DisplayMetrics metrics = getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
setMyEraseSize(40);
setColor(Color.GRAY);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBackground(canvas);
drawMyCircle(canvas);
}
//画圆
private void drawMyCircle(Canvas canvas) {
canvas.drawCircle(x,y,100,paint1);
}
//画背景颜色
private void drawBackground(Canvas canvas) {
Rect rect=new Rect(0,0,screenWidth,screenHeight);
canvas.drawRect(rect,paint2);
}
public boolean onTouchEvent(MotionEvent event){
final int x = (int) event.getX();// 获取当前触摸点的X轴坐标
final int y = (int) event.getY(); // 获取当前触摸点的Y轴坐标
this.x=x;this.y=y;
invalidate(); // 重绘画布
return true;
}
//设置橡皮擦大小
public void setMyEraseSize(int size){
paint1= new Paint();
paint1.reset();
paint1.setAntiAlias(true);//抗锯齿
paint1.setDither(true);//防抖动
paint1.setColor(Color.WHITE);
paint1.setStrokeWidth(size);
paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
BlurMaskFilter bmf=new BlurMaskFilter((0.5f), BlurMaskFilter.Blur.SOLID);
paint1.setMaskFilter(bmf);
paint1.setStyle(Paint.Style.FILL);
paint1.setStrokeJoin(Paint.Join.ROUND);
paint1.setStrokeCap(Paint.Cap.ROUND);
paint1.setSubpixelText(true);
paint1.setTextSize(50);
}
//设置比颜色
public void setColor(int color){
paint2=new Paint();
paint2.reset();
paint2.setAntiAlias(true);//抗锯齿
paint2.setDither(true);//防抖动
paint2.setStrokeWidth(5);
paint2.setTextSize(50);
paint2.setSubpixelText(true);
BlurMaskFilter bmf=new BlurMaskFilter((0.5f), BlurMaskFilter.Blur.SOLID);
paint2.setMaskFilter(bmf);
paint2.setPathEffect(new CornerPathEffect(20));
paint2.setStyle(Paint.Style.FILL);
paint2.setStrokeJoin(Paint.Join.ROUND);
paint2.setStrokeCap(Paint.Cap.ROUND);
paint2.setColor(color);
}
}
分析:
簡単に言えば、実際には、アイデアを使用することです:
2本のペン、背景(黒い布)を塗装する責任1、責任消しゴム機能(円)で、原因活動へのこの時間は透明であるので、あなたが直接することができますそれは再描画し、次の層を見て、それから指が移動したときに位置消しゴム(丸)を更新します。コードは非常に簡単です、私はあなたが理解できると信じて!!
どうでしょうか?それは単純ではないですか?
誰もが効果を確認した後、ここでは、このデモの他の方法と組み合わせることを可能にするために:
public class MainActivity extends Activity {
private WindowManager windowManager;
private WindowManager.LayoutParams wmParams,wm;
private int wmType;
private MyImageView myImageView;
private ImageView view;
private final int OVERLAY_PERMISSION_REQ_CODE = 1234;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (checkBallPermission()) startProgram();
}
//检查是否有悬浮窗权限
private boolean checkBallPermission()
{
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if(!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent,OVERLAY_PERMISSION_REQ_CODE);
return false;
}
}
return true;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e("SearchPrint","onActivityResult");
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
if(android.os.Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this))
{
Toast.makeText(MainActivity.this, this.getResources().getString(R.string.ballfail), Toast.LENGTH_SHORT).show();
this.finish();
}
else {
startProgram();
}
}
}
}
private void startProgram() {
initView();
show();
addListener();
}
private void addListener() {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hide();
finish();
}
});
}
private void hide(){
try{
windowManager.removeView(myImageView);
windowManager.removeView(view);
}catch (Exception e){
e.printStackTrace();
Log.e("SearchPrint","removeView:"+e.getMessage());
}
}
private void show() {
try{
windowManager.addView(myImageView,wmParams);
windowManager.addView(view,wm);
}catch (Exception e){
e.printStackTrace();
Log.e("SearchPrint","addView:"+e.getMessage());
}
}
private void initView() {
myImageView=new MyImageView(this);
view=new ImageView(this);
view.setBackgroundResource(R.drawable.exit);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
wmType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
wmType = WindowManager.LayoutParams.TYPE_PHONE;
}
windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
wmParams = new WindowManager.LayoutParams();
wmParams.type = wmType;
wmParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.gravity = Gravity.LEFT | Gravity.TOP;
wmParams.x = 0;
wmParams.y = 0;
wmParams.width = WindowManager.LayoutParams.MATCH_PARENT;
wmParams.height = WindowManager.LayoutParams.MATCH_PARENT;
wmParams.format = PixelFormat.RGBA_8888;
wm = new WindowManager.LayoutParams();
wm.type = wmType;
wm.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
wm.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wm.gravity = Gravity.RIGHT | Gravity.TOP;
wm.x = 0;
wm.y = 0;
wm.width = 100;
wm.height = 100;
wm.format = PixelFormat.RGBA_8888;
}
}
第四に、他の
あなたはサーチライトは、カスタム画像の外にある場合は、直接結合BitmapShaderとShapeDrawableを使用するのがより簡単ですが、多くの方法がオンラインにありますが、あなたはまた、メソッド内のギャラリーから写真の選択を追加することができ、すべてがシンプルに来て、 、スペースの制約のために、もはやそこに記載されていません。
オリジナルの記事、複製、リンク追加してくださいhttps://www.jianshu.com/p/438e5c7f3ba7を
ます。https://www.jianshu.com/p/438e5c7f3ba7で再現