2011-08-10 33 views
0

我正在創建一個吉他應用程序。它有一個相對的佈局,用於顯示吉他指板的圖像視圖,底部是一個保持一些按鈕的線性佈局。如果我想突出顯示指板上的音符,就會出現問題。我創建了一個客戶可繪製視圖,當我將它添加到保存圖像視圖的相對佈局時,它突出顯示,但保持某些按鈕的線性佈局消失。爲什麼?我需要做什麼?Android如何以編程方式添加自定義視圖而不影響佈局的其餘部分

佈局

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <!-- Top line --> 
    <LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:background="@drawable/bg_black" 
     android:orientation="horizontal" 
     android:id="@+id/appHeader"> 
     <TextView android:id="@+id/headerText" android:text="@string/app_name" 
      android:layout_width="wrap_content" android:layout_height="wrap_content" 
      android:textColor="@android:color/white" android:textSize="17dip" android:textStyle="bold" 
      android:gravity="center" android:paddingTop="2dip" android:paddingBottom="2dip" 
      android:layout_weight="1" />  
     <SeekBar android:layout_height="wrap_content" 
       android:id="@+id/seek_bar" 
       android:layout_width="300dip" 
       android:paddingTop="2dip" 
       android:paddingBottom="2dip" 
       android:paddingRight="4dip" 
       android:saveEnabled="true" 
       android:max="100" 
       android:progress="50"> 
       </SeekBar>     
    </LinearLayout> 
    <!-- Middle Guitar to scroll left-right--> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/fretboard_layout" 
     android:orientation="horizontal" 
     android:layout_width="2040dip" 
     android:layout_height="wrap_content" 
     > 
     <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/guitar_fretboard" 
      android:scaleType="center" 
      android:background="@drawable/bg_black" 
      android:src="@drawable/mina_fretboard_1951x218" 
     /> 
    </RelativeLayout> 
    <!-- Bottom Buttons--> 
    <LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:background="@drawable/bg_black" 
     android:gravity="center_horizontal|center_vertical" 
     android:orientation="horizontal"> 
      <LinearLayout 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingTop="2dip" 
      android:orientation="horizontal"> 
       <Button 
       android:id="@+id/choose_tune_button" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:drawableTop="@drawable/music" 
       android:minWidth="96dip" 
       android:text="@string/choose_tune" 
       />   
       <Button 
       android:id="@+id/play_tune_button" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:drawableTop="@drawable/play_stop" 
       android:minWidth="96dip" 
       android:text="@string/play_tune" 
       /> 
       <Button 
       android:id="@+id/check_button" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:minWidth="96dip" 
       android:drawableTop="@drawable/check" 
       android:text="@string/check_notes" 
       /> 
       <Button 
       android:id="@+id/note_count_button" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:minWidth="96dip" 
       android:drawableTop="@drawable/number" 
       android:text="@string/note_count" 
       /> 
       <Button 
       android:id="@+id/options_button" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:minWidth="96dip" 
       android:drawableTop="@drawable/options_32"   
       android:text="@string/options" 
       />        

    </LinearLayout>    
    </LinearLayout> 
</LinearLayout> 

CustomDrawableView類用於突出

package com.veitch.learntomaster.grp.ui.activities; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.drawable.ShapeDrawable; 
import android.graphics.drawable.shapes.OvalShape; 
import android.view.View; 

public class CustomDrawableView extends View { 
    private ShapeDrawable mDrawable; 
    private int x; 
    private int y; 
    private int drawableWidth; 
    private int drawableHeight; 


    public CustomDrawableView(Context context, int x, int y, int drawableWidth, int drawableHeight) { 
     super(context); 

     this.x = x; 
     this.y = y; 
     this.drawableWidth = 30; 
     this.drawableHeight = 15; 

     mDrawable = new ShapeDrawable(new OvalShape()); 
     mDrawable.getPaint().setColor(0xff74AC23);//Green 

     mDrawable.setAlpha(128);//50% opacity? 
     mDrawable.setBounds(this.x, this.y, this.x + this.drawableWidth, this.y + this.drawableHeight); 
    } 

    protected void onDraw(Canvas canvas) { 
     mDrawable.draw(canvas); 
    }  

    public int getX() { 
    return x; 
} 

public void setX(int x) { 
    this.x = x; 
} 

public int getY() { 
    return y; 
} 

public void setY(int y) { 
    this.y = y; 
} 


public void setDrawableWidth(int drawableWidth) { 
    this.drawableWidth = drawableWidth; 
} 

public int getDrawableWidth() { 
    return drawableWidth; 
} 


public void setDrawableHeight(int drawableHeight) { 
    this.drawableHeight = drawableHeight; 
} 

public int getDrawableHeight() { 
    return drawableHeight; 
} 

} 

主要活動,調用CustomerDrawableView

userPlayedHighlightView = new CustomDrawableView(this,x,y,HIGHLIGHT_WIDTH,HIGHLIGHT_HEIGHT); 

fretboardLayout.addView(userPlayedHighlightView); 

回答

2

我會用你的問題的另一種方法。我會構建一個FredboardView,它能夠在其onDraw方法中繪製突出顯示的筆記。這個視圖可以添加到你的佈局xml中。如果你想高亮一張紙條,這個視圖應該有一個方法來做到這一點,比如setHihglightedNote(note),你不需要每次用戶做某事時都在佈局中添加一些東西。

編輯:根據位置其得出了一些可繪自定義視圖的

實施例。

public class PositionIndicator extends View { 

    private static final int OFFSET = 2; 
    private Drawable on, off; 
    private int width, height; 
    private int size = 5; 
    private int position = 0; 
    private Paint paint; 

    public PositionIndicator(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     // init 
     on = context.getResources().getDrawable(R.drawable.dot_green); 
     off = context.getResources().getDrawable(R.drawable.dot_grey); 

     paint = new Paint(); 
     paint.setARGB(0, 0, 0, 0); 
    } 

    /** 
    * Set size of indicator. 
    * @param size Size. 
    */ 
    public void setSize(int size) { 
     if(size >= 0) 
      this.size = size; 
     this.invalidate(); 
    } 

    /** 
    * Set position of indicator. 
    * @param position Position. 
    */ 
    public void setPosition(int position) { 
     if(position >= 0 && position <= size) 
      this.position = position; 
     this.invalidate(); 
    } 

    private Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      switch(msg.what) { 
       case C.POSITION_CHANGED: 
        setPosition(msg.arg1); 
        break; 
      } 
     } 
    }; 

    public Handler getHandler() { 
     return handler; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public void onDraw(Canvas canvas) { 
     // draw transparent rectangle to clean area 
     canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint); 
     for(int i = 0; i < size; i++) { 
      // draw current 
      if(i+1 == position) { 
       on.setBounds(i*width+i*OFFSET, 0, i*width+i*OFFSET+width, height); 
       on.draw(canvas); 
      // draw others 
      } else { 
       off.setBounds(i*width+i*OFFSET, 0, i*width+i*OFFSET+width, height); 
       off.draw(canvas); 
      } 
     } 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    protected void onMeasure(int width, int height) { 
     super.onMeasure(width, height); 
     setMeasuredDimension(this.getMeasuredWidth(), this.getMeasuredHeight()); 
     this.width = (this.getMeasuredWidth() - ((size-1) * OFFSET))/size; 
     this.height = this.getMeasuredHeight(); 
    } 

} 
+0

感謝您的建議。我嘗試過,但不幸的是,指板圖像根本不渲染:<在佈局xml中,我用自定義的FretboardView替換了ImageView。 FretboardView類現在擴展了ImageView,它有一個setHighlightNote(note)方法,我從我的主Activity調用。但是,指板圖像根本不顯示。我想知道是否需要在FretboardView(Context context,AttributeSet attrs)構造函數中執行任何操作來檢索src圖像? – TomVeitch

+0

一個解決方案是將圖像硬編碼到FredboardView中,並在onDraw中自己繪製。否則,你需要將ViewGroup擴展到你的FretboardView。 – dbrettschneider

+0

我在上面的答案中提供了一些實用的代碼。希望有所幫助。那我怎麼解決它。 – dbrettschneider

相關問題