2013-06-11 3 views
1

순전히 자바 코드로 만든 사용자 정의보기가 있습니다. 뷰의 인스턴스를 만들고 컨텐트 뷰를 뷰 객체로 설정하면 잘 동작합니다. 하나; 내가 XML로 뷰를 임베드 할 때, 앱은 타임 아웃 에러로 작업을 멈춘다.동적 사용자 정의보기를 XML 레이아웃에 포함시키는 방법은 무엇입니까?

보기 코드 :

package com.example.dcubebluetooth; 

import android.view.View; 
import android.view.MotionEvent; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.Button; 
import android.widget.Toast; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.Config; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.util.AttributeSet; 

public class LEDView extends View{ 

    Paint background = new Paint(); 
    Paint white = new Paint(); 
    Paint red = new Paint(); 

    Bitmap grid; 
    Canvas ledDrawer = new Canvas(); 

    boolean[][][] states = new boolean[4][4][4]; 

    int currentLayer = 0; 

    Button l1; 
    Button l2; 
    Button l3; 
    Button l4; 

    public LEDView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     initialize(); 
    } 

    public void initialize(){ 
     /* 
     l1 = (Button) findViewById(R.id.layer1); 
     l1.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Toast.makeText(getContext(), "Test", Toast.LENGTH_LONG).show(); 
      } 
     }); 
     l2 = (Button) findViewById(R.id.layer2); 
     l3 = (Button) findViewById(R.id.layer3); 
     l4 = (Button) findViewById(R.id.layer4); 
     */ 
     setLayoutParams(new LayoutParams(400, 400)); 

     background.setARGB(255, 0, 0, 0); 
     white.setARGB(255, 255, 255, 255); 
     red.setARGB(255, 255, 0, 0); 

     grid = Bitmap.createBitmap(400, 400, Config.RGB_565); 
     ledDrawer.setBitmap(grid); 
     //ledDrawer.drawPaint(background); 

     for(int i=0; i<states.length; i++){ 
      for(int j=0; j<states[0].length; j++){ 
       for(int k=0; k<states[0][0].length; k++){ 
        states[i][j][k] = false; 
       } 
      } 
     } 

     drawGrid(currentLayer); 
    } 


    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawBitmap(grid, 0, 0, null); 
    } 

    private void drawGrid(int layer) { 
     //ledDrawer.drawPaint(background); 

     for(int y=0; y<4; y++){ 
      for(int x=0; x<4; x++){ 
       Paint p = (states[layer][x][y] == true) ? red : white; 
       ledDrawer.drawCircle((100*x)+50, (100*y)+50, 40, p); 
      } 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     int x = (int) (event.getX())/100; 
     int y = (int) (event.getY())/100; 

     states[currentLayer][x][y] = !states[currentLayer][x][y]; 

     drawGrid(currentLayer); 

     invalidate(); 

     return super.onTouchEvent(event); 
    } 

} 

XML 코드 :

<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.dcubebluetooth.LEDView 
     android:id="@+id/lEDView1" 
     android:layout_width="400px" 
     android:layout_height="400px" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentLeft="true"/> 

<Button 
     android:id="@+id/layer1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/lEDView1" 
     android:layout_marginTop="50px" 
     android:text="Layer1" 
     android:textSize="12dp" /> 

    <Button 
     android:id="@+id/layer2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBottom="@id/layer1" 
     android:layout_toRightOf="@id/layer1" 
     android:text="Layer2" 
     android:textSize="12dp" /> 

    <Button 
     android:id="@+id/layer3" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBottom="@id/layer2" 
     android:layout_toRightOf="@id/layer2" 
     android:text="Layer3" 
     android:textSize="12dp" /> 

    <Button 
     android:id="@+id/layer4" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBottom="@id/layer3" 
     android:layout_toRightOf="@id/layer3" 
     android:text="Layer4" 
     android:textSize="12dp" /> 

</RelativeLayout> 

내가 머리 또는 로그 캣의 꼬리를 만들 수 없습니다. 인스턴스 또는 무언가를 생성하는 중 일부 문제가 발생했습니다. :

06-11 10:50:29.079: E/AndroidRuntime(19143): FATAL EXCEPTION: main 
06-11 10:50:29.079: E/AndroidRuntime(19143): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dcubebluetooth/com.example.dcubebluetooth.MainActivity}: android.view.InflateException: Binary XML file line #11: Error inflating class com.example.dcubebluetooth.LEDView 
06-11 10:50:29.079: E/AndroidRuntime(19143): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967) 

마지막으로 중요한 부분을 제외하고 모든 것을 주석 처리하려고 시도합니다. 나는 그 문제를 정확하게 지적 할 수 없다.

xml에 이것을 사용해야하는 이유는 버튼을 쉽게 추가 할 수 있기 때문입니다.

+0

전체 스택 추적 – user1781028

답변

2

Android에서 정의하지 않은 사용자 정의보기의 생성자 중 하나를 호출합니다. 따라서 당신은 당신의 사용자 정의보기에 대한 모든 생성자를 만들어야합니다

public LEDView(Context context) { 
    super(context); 
    initialize(); 
} 
public LEDView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initialize(); 
} 
public LEDView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    initialize(); 
} 
+0

아 저주를 추가하십시오. 실례지만 제 수업 시간에 간단한 수정으로 기간을 낭비했습니다. 고마워. 이 생성자가 무엇인지, 문맥 이외의 매개 변수와 안드로이드가 어떻게 호출하는지에 대한 링크 – user2316667

+0

http://developer.android.com/reference/android/view/View.html#View(android.content.Context) 및 다음 섹션을 참조하십시오. 코드 샘플과 설명도 있습니다. http://developer.android.com/training/custom-views/create-view.html#applyattr –

관련 문제