开发者

Android how can you add a custom view programmatically without affecting rest of layout

I'm creating a guitar app. It has an relative layout holding an image view to display the guitar fretboard and at the bottom a linear layout holding some Buttons. The issue occurs when I want to highlight the note on the fretboard. I've created a customer drawable view and when I add it to the relative layout holding an image view, it highlights, BUT the linear layout holding some buttons disappears. Why? What do I need to do?

Layout

<?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 class for highlighting

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;
 }

}

Main Activity, calling the CustomerDrawableView

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

fretboardLayout.addView(userPlayedHighlightView);


I would use another approach for your problem. I would built a FredboardView which is capable of drawing a highlighted note in its onDraw method. This View could be added in your layout xml. If you want to highglight a note the view should have a method to do this like setHihglightedNote(note) and you would not have to add something to the layout everytime the user does something.

EDIT:

Example of a custom view which draws some drawables according to a position.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜