2011-04-25 78 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

相關問題