【问题标题】:How to pass variables to custom View before onDraw() is called?如何在调用 onDraw() 之前将变量传递给自定义视图?
【发布时间】:2014-08-21 05:57:50
【问题描述】:

我想要达到的目标:

  • 在我的布局 mainContainer 中测量容器 View,该容器在 XML 中定义
  • 在调用onDraw() 之前将mainContainer's width and height 传递给不同的自定义View
  • 我想传递宽度和高度,以便自定义 View 知道使用坐标在哪里绘制 canvas.drawBitmap
  • 自定义视图将由代码创建 programmatically

如何在调用 onDraw() 之前将测量的 int 宽度和 int 高度传递给我的自定义 View?

自定义视图

public class AvatarView extends ImageView {

private Bitmap body;
private Bitmap hat;

public AvatarView(Context context) {
    super(context);
    init();
}

public AvatarView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public AvatarView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

private void init() {
    body = BitmapFactory.decodeResource(getResources(), R.drawable.battle_run_char);
    hat = BitmapFactory.decodeResource(getResources(), R.drawable.red_cartoon_hat);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(body, x, y, null);
    canvas.drawBitmap(hat, x, y, null);
}
}

片段

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_customize_avatar, container, false);
    final RelativeLayout mainContainer = (RelativeLayout) view.findViewById(R.id.main_container);
    TwoWayView inventoryList = (TwoWayView) view.findViewById(R.id.inventory);

    inventoryList.setAdapter(null);

    inventoryList.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

        }
    });

    mainContainer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @SuppressLint("NewApi")
        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() {
            // Retrieve the width and height
            containerWidth = mainContainer.getWidth();
            containerHeight = mainContainer.getHeight();

            // Remove global listener
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
                mainContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            else
                mainContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    });

    return view;
}

XML

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:clickable="true"
android:background="#fff" >

<com.walintukai.lfdate.CustomTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:textStyle="bold"
    android:textColor="#fff"
    android:textSize="20sp"
    android:textAllCaps="true"
    android:text="@string/customize_avatar"
    android:background="#009BFF" />

<RelativeLayout
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

<org.lucasr.twowayview.TwoWayView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/inventory"
    style="@style/HorizontalListView"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:drawSelectorOnTop="false"
    android:background="#f3f3f3" />

</LinearLayout>

【问题讨论】:

  • 你的意思是在你的AvatarView类中传递containerWidthcontainerHeight

标签: android constructor android-custom-view custom-view


【解决方案1】:

您需要做的是在您的 AvatarView 中添加一个标志,以检查您是否要在您的 onDraw 方法中呈现它。

样本:

   public class AvatarView extends ImageView {

    private Bitmap body;
    private Bitmap hat;
    private int containerHeight;
    private int containerWidth;
    private boolean isRender = false;

    public AvatarView(Context context) {
        super(context);
        init();
    }

    public AvatarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AvatarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void setMeasure(int containerWidth, int containerHeight )
    {
        this.containerHeight = containerHeight;
        this.containerWidth = containerWidth;
    }

    private void init() {
        body = BitmapFactory.decodeResource(getResources(), R.drawable.battle_run_char);
        hat = BitmapFactory.decodeResource(getResources(), R.drawable.red_cartoon_hat);
    }

    public void setRender(boolean render)
    {
       isRender = render;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(isRender )
        {
            canvas.drawBitmap(body, x, y, null);
            canvas.drawBitmap(hat, x, y, null);
        }

    }
    }

现在,当您不调用setRender 并将其设置为true 时,它不会呈现。只需调用setMeasure 即可传递值。

首先你需要调用setMeasure,然后在你设置度量值之后调用setRender(true),然后调用invalidate()调用onDraw方法来渲染图像

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 2011-09-10
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多