【问题标题】:how to make custom view invalidate from activity如何使自定义视图从活动中失效
【发布时间】:2011-08-27 18:25:15
【问题描述】:

我有一个应用程序,我想在位图上放置 2 个圆圈。我有 2 个按钮,一个用于增加半径,一个用于减小半径。按钮从活动中的 xml 膨胀。活动的视图是自定义视图。我可以让按钮显示在视图上,并且两者都相应地改变了半径变量。到目前为止,一切都很好。单击任一按钮时,我无法使视图无效。应该发生的是,当单击按钮时,半径会发生变化,然后重新绘制画布以显示半径变化。如何从 onclick() 调用无效?我不确定这是否是最好的方法。谢谢。 .

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Jjilapp extends Activity {




    private static final String TAG = "*********jjil";


    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.touchview);
        final TouchView touchView = (TouchView)findViewById(R.id.touchview); 
        final HorizontalSlider slider = (HorizontalSlider)findViewById(R.id.slider); 
        touchView.initSlider(slider);

        Button plus = (Button)findViewById(R.id.plus);
        plus.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Log.e(TAG, "onClickplus");
                TouchView.setRadius(TouchView.getRadius() + 5);
                Log.e(TAG, "radius = "+TouchView.getRadius());
            }}) ;





         Button minus = (Button)findViewById(R.id.minus);
         minus.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub

                TouchView.setRadius(TouchView.getRadius() - 5);
                Log.e(TAG, "radius = "+TouchView.getRadius());

                TouchView.invalidate();// DOESN'T WORK***************

            }}) ;







    }//end of oncreate




}//end of jjilapp

.

public class TouchView extends View{



    private static int radius = 50;




    public TouchView(Context context) {
        super(context);

    }




    public TouchView(Context context, AttributeSet attr) {
        super(context,attr);
        Log.e(TAG, "++++++++++ inside touchview constructor");





    pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);         
    pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); 
    pTouch.setColor(Color.TRANSPARENT);
    pTouch.setStyle(Paint.Style.STROKE);


    }// end of touchView constructor






    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);

        Log.e(TAG, "******about to draw bgr ");
        canvas.drawBitmap(bgr, 0, 0, null);



       canvas.drawCircle(centreX, centreY, radius,pTouch);
       canvas.drawCircle(centreA, centreB, radius,pTouch);
        }

    }//end of onDraw



    public static int getRadius() {
        return radius;
    }




    public static void setRadius(int r) {
        radius = r;
    }




}

【问题讨论】:

  • 我很困惑。 touchView.invalidate(); 有什么问题?

标签: java android custom-view


【解决方案1】:

为什么radius 和相关的get/set 方法是静态的?这意味着即使您的应用程序中同时有多个TouchViews,它们的半径也始终相同。

首先从这三个东西中删除static,这样每个TouchView 都有自己的半径。接下来,不要从TouchView 类本身调用TouchView 方法,而是从您在上面命名为touchView 的实际TouchView 实例调用它们。 (例如 touchView.setRadius(...) 而不是 TouchView.setRadius(...)。)

invalidate 不是 View 的静态方法,因此您不能将其作为一个方法调用。视图应该invalidate 自己,当它们的属性发生变化时,需要它们重绘。由于半径是您的TouchView 的一个这样的属性,它应该在setRadius 方法的末尾调用invalidate()。这将允许您从您的 Activity 中删除任何不属于它们的直接 invalidate 调用。

【讨论】:

  • 感谢您提供的信息。您描述的方式是视图应该更新自己的方式。我将更改设置器以反映这一点。:)
【解决方案2】:

您使用的是类的函数而不是对象,这意味着您使用的是:

TouchView.function()

而不是

touchView.function()

invalidate 不是静态函数,所以需要直接在对象本身上调用。如果您从非 UI 线程更新视图,请不要忘记使用 postInvalidate()。

【讨论】:

  • OnClickListeners 将始终从 UI 线程调用,并且任何正确的 Android 代码将永远不会从 UI 线程以外的线程更新视图。 (这就是它被称为 UI 线程的原因。:))
  • 嗯,这就是为什么 id 没有说“将您的代码更改为...”。我只觉得值得一提的是,在从非 ui 线程调用的情况下,postInvalidate 是有序的。
猜你喜欢
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
相关资源
最近更新 更多