2011-04-25 77 views

回答

39

用xml Layout中的FrameLayout封装你的surfaceView。然后将你的按钮添加到相同的FrameLayout。确保它们放置在表面视图下方,以便它们在其上绘制。 (可能是一个好主意,他们捆绑在另一个布局,并添加到FrameLayout里。)

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <SurfaceView android:id="@+id/surfaceView1" android:layout_width="wrap_content" android:layout_height="wrap_content"></SurfaceView> 
    <LinearLayout android:id="@+id/linearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content"> 
     <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
     <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
    </LinearLayout> 
</FrameLayout> 
+0

我以编程方式创建了surfaceView,但是如何与XML中的一个链接。 – m4n07 2011-04-26 05:00:53

+1

我不得不在xml中添加这样的内容 – m4n07 2011-05-02 09:17:20

+0

我使用这个xml作为我的活动,其中我当用户点击自定义TouchImageView的ImageView时,想要初始化SurfaceView,该ImageView具有缩放和捏合功能的ImageView。我想要做的是 - (1)它显示来自web服务的图像,我已经用AQuery完成了。 (2)当用户在CAB的编辑选项上选择时,它使得在图像上具有可拖动的编辑文本的表面视图。 @androidika你能帮助我吗? – 2015-07-07 12:31:51

29

谢谢你这么多Androidica ..

你的XML已经帮我找出以下解决方案编程方式不使用任何xml ..

public class LudoActivity extends Activity implements OnClickListener { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 

     FrameLayout game = new FrameLayout(this); 
     GameView gameView = new GameView (this); 
     LinearLayout gameWidgets = new LinearLayout (this); 

     Button endGameButton = new Button(this); 
     TextView myText = new TextView(this); 

     endGameButton.setWidth(300); 
     endGameButton.setText("Start Game"); 
     myText.setText("rIZ..i"); 

     gameWidgets.addView(myText); 
     gameWidgets.addView(endGameButton);  

     game.addView(gameView); 
     game.addView(gameWidgets); 

     setContentView(game); 
     endGameButton.setOnClickListener(this); 
    } 

    public void onClick(View v) { 
     Intent intent = new Intent(this, LudoActivity.class); 
     startActivity(intent); 
     // re-starts this activity from game-view. add this.finish(); to remove from stack 
    } 
} 

while GameView is;

public class GameView extends SurfaceView { 

    public GameView(Context context) { 
     super(context); 

     /* 
     * your code 
     */ 
    } 
} 
+0

非常感谢这个代码版本,在另一个答案中发布的XML困惑了我。 – 2012-10-19 20:52:11

+0

它是我的荣幸...欢迎您 – 2012-10-23 07:21:22

3

我们可以很容易地使用框架布局进行表面视图绘制。 这样

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 
<FrameLayout 
    android:id="@+id/frameLayout" 
    android:layout_width="fill_parent" 
    android:layout_height="430dp"/> 
    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="50dp" 
     android:gravity="center_horizontal" 
     android:layout_gravity="bottom" 
     android:background="#c2300f"> 

     <Button 
      android:id="@+id/buttonColor" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Color" /> 
    </LinearLayout>  
</LinearLayout> 

及主要活动是

package com.example.surfacetuto; 


import android.app.Activity; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.FrameLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

public class MainActivity extends Activity implements OnClickListener{ 
    DrawingSurface ds; 
    FrameLayout frm; 
    Button btnC; 
    int color=0xfff00000; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ds=new DrawingSurface(this); 
    setContentView(R.layout.activity_main); 


    frm=(FrameLayout)findViewById(R.id.frameLayout); 
    frm.addView(ds); 

    btnC=(Button)findViewById(R.id.buttonColor); 

    btnC.setOnClickListener(this); 
} 
@Override 
public void onClick(View v) { 
    // TODO Auto-generated method stub 
    switch (v.getId()) { 

    case R.id.buttonColor: 
     Toast.makeText(getApplicationContext(), "Color", 2).show(); 
     ds.colorNew(); 

     break; 

    default: 
     break; 
    } 
} 
    } 

和拉丝面类是

package com.example.surfacetuto; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.graphics.Paint.Cap; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.DisplayMetrics; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.Toast; 

    public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback { 

     Canvas cacheCanvas; 
     Bitmap backBuffer; 
     int width, height, clientHeight; 
     Paint paint; 
     Context context; 
     SurfaceHolder mHolder; 


public DrawingSurface(Context context) { 
    super(context); 
    this.context = context; 
    init(); 
} 
public DrawingSurface(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    this.context = context;  
    init(); 
} 

private void init() { 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 

} 

int lastX, lastY, currX, currY; 
boolean isDeleting; 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
    super.onTouchEvent(event); 
    int action = event.getAction(); 
    switch(action & MotionEvent.ACTION_MASK) { 
    case MotionEvent.ACTION_DOWN: 
     lastX = (int) event.getX(); 
     lastY = (int) event.getY(); 
     break; 
    case MotionEvent.ACTION_MOVE: 
     if(isDeleting) break; 

     currX = (int) event.getX(); 
     currY = (int) event.getY(); 
     cacheCanvas.drawLine(lastX, lastY, currX, currY, paint); 
     lastX = currX; 
     lastY = currY; 

     break; 
    case MotionEvent.ACTION_UP: 
     if(isDeleting) isDeleting = false; 
     break; 
    case MotionEvent.ACTION_POINTER_DOWN: 
     cacheCanvas.drawColor(Color.WHITE); 
     isDeleting = true; 
     break; 
    case MotionEvent.ACTION_POINTER_UP: 
     break; 
    } 
    draw(); 
    return true; 
} 

protected void draw() { 

    if(clientHeight==0) { 
     clientHeight = getClientHeight(); 
     height = clientHeight; 
     backBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
     cacheCanvas.setBitmap(backBuffer); 
     cacheCanvas.drawColor(Color.WHITE); 
    } 
    Canvas canvas = null; 
    try{ 
     canvas = mHolder.lockCanvas(null); 

     canvas.drawBitmap(backBuffer, 0,0, paint); 
    }catch(Exception ex){ 
     ex.printStackTrace(); 
    }finally{ 
     if(mHolder!=null) mHolder.unlockCanvasAndPost(canvas); 
    } 
} 

private int getClientHeight() { 
    Rect rect= new Rect();  
    Window window = ((Activity)context).getWindow();  
    window.getDecorView().getWindowVisibleDisplayFrame(rect);  
    int statusBarHeight= rect.top;  
    int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop();  
    int titleBarHeight= contentViewTop - statusBarHeight; 
    return ((Activity)context).getWindowManager().getDefaultDisplay(). 
      getHeight() - statusBarHeight - titleBarHeight; 
} 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
} 

public void surfaceCreated(SurfaceHolder holder) { 

    width = getWidth(); 
    height = getHeight(); 
    cacheCanvas = new Canvas(); 
    backBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    cacheCanvas.setBitmap(backBuffer); 
    cacheCanvas.drawColor(Color.WHITE); 
    paint = new Paint(); 
    paint.setColor(Color.BLUE); 
    paint.setStrokeWidth(10); 
    paint.setStrokeCap(Paint.Cap.ROUND); 
    paint.setStrokeJoin(Paint.Join.ROUND); 
    draw(); 

} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    boolean retry = true; 
     thread.setRunning(false); 
     while (retry) { 
      try { 
       thread.join(); 
       retry = false; 
      } catch (InterruptedException e) { 
       // we will try it again and again... 
      } 
     } 
} 

public void colorNew() { 
    // TODO Auto-generated method stub 
    paint.setColor(Color.GRAY); 
} 


    } 
7

使自己的按钮:触摸事件

import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Matrix; 
import android.graphics.RectF; 

    public class GButton 
    { 
     public Matrix btn_matrix = new Matrix(); 

     public RectF btn_rect; 

     float width; 
     float height; 
     Bitmap bg; 

     public GButton(float width, float height, Bitmap bg) 
     { 
      this.width = width; 
      this.height = height; 
      this.bg = bg; 

      btn_rect = new RectF(0, 0, width, height); 
     } 

     public void setPosition(float x, float y) 
     { 
      btn_matrix.setTranslate(x, y); 
      btn_matrix.mapRect(btn_rect); 
     } 

     public void draw(Canvas canvas) 
     { 
      canvas.drawBitmap(bg, btn_matrix, null); 
     } 
    } 

float x = ev.getX(); 
float y = ev.getY(); 
if (my_button.btn_rect.contains(x, y)) 
{ 
    // handle on touch here 
} 

或者,甚至更好,如果你也想旋转按钮,它不会是轴对齐,然后使用反转矩阵,而不是mapRect映射的接触点X,Y:

float pts[] = {x, y};    
my_button.invert_matrix.mapPoints(pts);   
if (my_button.btn_rect.contains(pts[0], pts[1]) 
{ 
    // handle on touch here 
} 
+0

感谢您的代码,希望它能帮助我。 – 2015-07-07 12:34:10

+0

谢谢,它适合我! – 2016-12-27 07:15:18

+0

我想看一个帖子,比较用这种方法制作自己的按钮的一个优点,就是使用buttonwidget中的Button对象,就像在gruemeen4的答案中一样。我最近将我的游戏代码中的所有自定义按钮更改为Button对象,并且它看起来不像点击那样好。 – Androidcoder 2017-10-16 20:50:14

相关问题