Solutions to overwrite other components due to transparent surfaceview settings

Source: Internet
Author: User
Tags gety

Previously, we used surfaceview to draw a joystick disc in the project and set surfaceview transparency. However, this would cause surfaceview components to overwrite other components, which is generally irrelevant, in other cases, the pull-up and drop-down functions are similar. The layout to be pulled is located at the top to overwrite other components. The following figure shows the transparent usage of surfaceview:

Setzorderontop (true); mholder. setformat (pixelformat. Transparent); // set the background to transparent.

This will cause surfaceview to be at the top of the layout, even if you have set bringtotop, there are two solutions to this problem:

First: Using popupwindow or a function similar to a floating small form, I tested that they will not be overwritten by surfaceview, but this solution is only applicable to the pop-up of click implementation components, it is not possible to pull up and drag to display the build (the pull up layout here refers to a part outside the visible form). Unfortunately, you need to specify the pull up in the project, instead of clicking to implement the component pop-up function, this solution is not applicable to my situation. So I found the second case.

Second:

Write a class to inherit the view, and then use the ontouchevent and ondraw methods to draw images. For details, see the code:

Jockey_left class: inherits View

Package COM. example. test; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapfactory; import android. graphics. canvas; import android. graphics. paint; import android. graphics. point; import android. util. attributeset; import android. view. motionevent; import android. view. view; public class jockey_left extends view {private Bitmap bitmap; Public point mrockerposition; Public Point mctrlpoint; private int mrudderradius = 25; Public int mwheelradius = 80; private float scale; Public int ishide = 0; private paint mpaint; Public jockey_left (context) {super (context);} public jockey_left (context, attributeset attrs) {super (context, attrs);} public void Init (float scale) {This. scale = scale; mrudderradius = dip2px (15); mwheelradius = dip2px (45); bitmap = bitmapfactory. d Ecoderesource (getresources (), R. drawable. print2); bitmap = bitmap. createscaledbitmap (bitmap, mrudderradius * 2, mrudderradius * 2, false); mctrlpoint = new point (mrudderradius + mwheelradius), (mrudderradius + mwheelradius); mpaint = new paint (); mpaint. setantialias (true); mrockerposition = new point (mctrlpoint);} public int dip2px (float dpvalue) {return (INT) (dpvalue * scale + 0.5f);} public canvas Canvas; @ overrideprotected void ondraw (canvas) {If (Bitmap! = NULL) {// canvas. drawcolor (color. transparent, mode. clear); // This. canvas = canvas; canvas. drawbitmap (bitmap, mrockerposition. x-mrudderradius, mrockerposition. y-mrudderradius, mpaint);} super. ondraw (canvas);} int Len; @ overridepublic Boolean ontouchevent (motionevent event) {try {If (ishide = 0) {Switch (event. getaction () {Case motionevent. action_down: Len = mathutils. getlength (mctrlpoint. x, mctrlpoint. y, event. getx (), event. gety (); // If the screen contact point is not within the rocker wave range, if (LEN> mwheelradius) {return true;} break; Case motionevent will not be processed. action_move: Len = mathutils. getlength (mctrlpoint. x, mctrlpoint. y, event. getx (), event. gety (); If (LEN <= mwheelradius) {// If the finger is in the active range of the joystick, the joystick is in the position of the finger touch mrockerposition. set (INT) event. getx (), (INT) event. gety ();} else {// set the joystick position so that it is at the edge of the joystick activity range mrockerposition = mathutils. getborderpoint (mctrlpoint, new point (INT) event. getx (), (INT) event. gety (), mwheelradius);} break; Case motionevent. action_up: mrockerposition = new point (mctrlpoint); break;} thread. sleep (40);} else {thread. sleep (200) ;}} catch (exception e) {} invalidate (); // update layout return true ;}}

Use touch to detect the touch point of the hand, update the position of the center dot, and then call invalidate (); To update the view background and implement the ondraw method to draw the image.

Appsinglerocker class: As a comparison, I use a class to inherit surfaceview and then implement background transparency.

Package COM. example. test; import android. annotation. suppresslint; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapfactory; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. graphics. pixelformat; import android. graphics. point; import android. graphics. porterduff. mode; import android. util. attributeset; import Android. view. motionevent; import android. view. surfaceholder; import android. view. surfaceview; import android. view. surfaceholder. callback; @ suppresslint ("viewconstructor") public class appsinglerocker extends surfaceview implements callback {private surfaceholder mholder; private paint mpaint; Public point mrockerposition; // The joystick position private point mctrlpoint; // the start position of the joystick is private int mrudderradius = 25; // The joystick radius is priva. Te int mwheelradius = 80; // rocker activity range radius private int batmaphw = 160; private int batmap2hw = 40; int ishide = 0; Bitmap bitmap, bitmap2; float scale; private singlerudderlistener listener = NULL; // Event Callback interface public static final int action_rudder = 1, action_attack_devicemove = 2, action_stop = 3, listener = 4; Public appsinglerocker (context, attributeset attrs) {super (context, attrs); this. Setkeepscreenon (true); Scale = context. getresources (). getdisplaymetrics (). density; mrudderradius = dip2px (15); // joystick radius mwheelradius = dip2px (45); // the radius of the joystick activity range mctrlpoint = new point (mrudderradius + mwheelradius ), (mrudderradius + mwheelradius); // the starting position of the joystick, batmaphw = (mwheelradius + mrudderradius) * 2; batmap2hw = mrudderradius * 2; mholder = getholder (); mholder. addcallback (this); mpaint = new paint (); mpain T. setantialias (true); setfocusable (true); setfocusableintouchmode (true); mrockerposition = new point (mctrlpoint); setzorderontop (true); mholder. setformat (pixelformat. transparent); // sets the background to transparent bitmap = bitmapfactory. decoderesource (getresources (), R. drawable. joystick_l_pad); bitmap = bitmap. createscaledbitmap (bitmap, batmaphw, batmaphw, false); bitmap2 = bitmapfactory. decoderesource (getresources (), R. dr Awable. print2); bitmap2 = bitmap. createscaledbitmap (bitmap2, batmap2hw, batmap2hw, false);} // obtain the screen width, height and density, and DP/PX public void getdisplaymetrics () {} public int dip2px (float dpvalue) {return (INT) (dpvalue * scale + 0.5f);} // callback interface public interface singlerudderlistener {void onsteeringwheelchanged (INT action, int angle );} // set the callback interface public void setsinglerudderlistener (singlerudderlistener rockerliste NER) {listener = rockerlistener;} int Len; @ overridepublic Boolean ontouchevent (motionevent event) {try {If (ishide = 0) {Switch (event. getaction () {Case motionevent. action_down: Len = mathutils. getlength (mctrlpoint. x, mctrlpoint. y, event. getx (), event. gety (); // If the screen contact point is not within the rocker wave range, if (LEN> mwheelradius) {return true;} break; Case motionevent will not be processed. action_move: Len = mathutils. getlength (mctrlpoint. X, Mctrlpoint. y, event. getx (), event. gety (); If (LEN <= mwheelradius) {// If the finger is in the active range of the joystick, the joystick is in the position of the finger touch mrockerposition. set (INT) event. getx (), (INT) event. gety ();} else {// set the joystick position so that it is at the edge of the joystick activity range mrockerposition = mathutils. getborderpoint (mctrlpoint, new point (INT) event. getx (), (INT) event. gety (), mwheelradius);} If (listener! = NULL) {float radian = mathutils. getradian (mctrlpoint, new point (INT) event. getx (), (INT) event. gety (); listener. onsteeringwheelchanged (action_rudder, getanglecouvert (radian);} break; Case motionevent. action_up: mrockerposition = new point (mctrlpoint); If (listener! = NULL) {listener. onsteeringwheelchanged (action_stop, 0);} break;} canvas_ OK (); thread. sleep (60);} else {thread. sleep (200) ;}} catch (exception e) {} return true;} public void singlerockerup () {mrockerposition = new point (mctrlpoint); listener. onsteeringwheelchanged (action_stop, 0);} // obtain the joystick offset from 0 to ° private int getanglecouvert (float radian) {int TMP = (INT) math. round (radian/math. pI * 180); If (TMP <0) {Return-TMP;} else {return 180 + (180-TMP) ;}} public void surfacecreated (surfaceholder holder) {canvas_ OK ();} public void surfacechanged (surfaceholder holder, int format, int width, int height) {} public void surfacedestroyed (surfaceholder holder) {} // you can specify whether to hide public void hided (int opt) {ishide = OPT; canvas_ OK ();} public void sethided (INT OPT) {ishide = OPT;}/*** returns whether the disc is hidden * @ return */Public int Geti Shided () {return ishide;} // draw the image public void canvas_ OK () {canvas = NULL; try {If (ishide = 0) {canvas = mholder. lockcanvas (); canvas. drawcolor (color. transparent, mode. clear); // clear the screen canvas. drawbitmap (bitmap, mctrlpoint. x-mwheelradius-mrudderradius, mctrlpoint. y-mwheelradius-mrudderradius, mpaint); canvas. drawbitmap (bitmap2, mrockerposition. x-mrudderradius, mrockerposition. y-mrudd Erradius, mpaint);} else {canvas = mholder. lockcanvas (); canvas. drawcolor (color. transparent, mode. clear); // clear the screen} catch (exception e) {e. printstacktrace ();} finally {If (canvas! = NULL) {mholder. unlockcanvasandpost (canvas );}}}}

Activity_main: This is my layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <com.example.test.Jockey_Left        android:layout_width="120dp"        android:layout_height="120dp"        android:id="@+id/left_jockey"        android:background="@drawable/joystick_l_pad"        ></com.example.test.Jockey_Left>    <Button         android:layout_width="60dp"        android:layout_height="60dp"        />            <com.example.test.AppSingleRocker        android:layout_width="120dp"        android:layout_height="120dp"        android:layout_alignParentRight="true"        android:layout_alignParentBottom="true"        ></com.example.test.AppSingleRocker>    <Button         android:layout_width="60dp"        android:layout_height="60dp"         android:layout_alignParentRight="true"        android:layout_alignParentBottom="true"        /></RelativeLayout>

Mainactivity: The displayed activity.

package com.example.test;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity {Jockey_Left jockey_left;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);jockey_left = (Jockey_Left)findViewById(R.id.left_jockey);jockey_left.init(getResources().getDisplayMetrics().density);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}}

Shows the display effect:

 

 

Obviously:

1. The button in the upper left corner is not overwritten, and the button in the lower right corner is overwritten.

2. The two disks use the same image, but the lower right corner of the disc has obvious serrations, while the upper left corner does not

3. The only disadvantage is that the smoothness in the upper left corner is not as good as that in the lower right corner.

 

Therefore, if the drawing area requires a rectangle, it is best to use surfaceview, because this increases the smoothness of the program. If the disc is required and other components cannot be overwritten, use the inherited view to implement it again.

 

Source code: http://download.csdn.net/detail/jwzhangjie/5816135 here at the same time to achieve the function of the disc

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.