Android, как вы можете добавить пользовательский вид программно, не затрагивая остальную часть макета - PullRequest
0 голосов
/ 10 августа 2011

Я создаю приложение для гитары.Он имеет относительную компоновку, содержащую вид изображения для отображения грифа гитары, а внизу линейную компоновку с некоторыми кнопками.Проблема возникает, когда я хочу выделить заметку на грифе.Я создал растягиваемый вид клиента, и когда я добавляю его в относительный макет, содержащий вид изображения, он выделяется, НО линейный макет с некоторыми кнопками исчезает.Зачем?Что мне нужно сделать?

Макет

<?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);

1 Ответ

2 голосов
/ 10 августа 2011

Я бы использовал другой подход к вашей проблеме. Я бы построил FredboardView, который способен рисовать выделенную заметку в методе onDraw. Это представление может быть добавлено в ваш макет XML. Если вы хотите выделить заметку, у представления должен быть способ сделать это, например setHihglightedNote(note), и вам не нужно будет добавлять что-то в макет каждый раз, когда пользователь что-то делает.

EDIT:

Пример пользовательского представления, которое рисует некоторые элементы рисования в соответствии с позицией.

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...