2011-08-27 3 views
1

저는 비트 맵에 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; 
    } 




} 
+0

나는 혼란 스럽다. touchView.invalidate();가 잘못되었습니다. – mibollma

답변

1

당신은 클래스의 기능이 아닌 객체를 사용하는 의미 당신이 사용하는 대신

touchView.function() 

무효화의

TouchView.function() 

정적 기능이 아닌, 당신이 호출 할 필요가 있도록 그것은 직접 객체 자체에 있습니다. UI가 아닌 스레드에서보기를 업데이트하는 경우 postInvalidate()를 사용하는 것을 잊지 마십시오.

+0

OnClickListeners는 UI 스레드에서 항상 호출되며 올바른 Android 코드는 UI 스레드가 아닌 스레드에서보기를 업데이트하지 않습니다. (이것이 UI 스레드라고하는 이유입니다. :) – adamp

+2

글쎄, ID가 "코드를 변경 ..."이라고 말하지 않은 이유입니다. 난 그저 언급할만한 가치가 있다고 생각했는데, 비 - ui 스레드로부터의 호출의 경우, postInvalidate가 순서대로 있다는 것을 알았다. –

+0

좋은 팁! – adamp

3

radius과 관련 get/set 메서드가 정적 인 이유는 무엇입니까? 즉, 앱에 여러 개의 TouchViews이있는 경우에도 항상 같은 반지름을 갖게됩니다.

각각 TouchView에 자체 반지름이 있도록이 세 가지에서 static을 제거하여 시작하십시오. 그런 다음 TouchView 메서드를 TouchView 클래스 자체에서 호출하는 대신 위에서 touchView이라는 실제 TouchView 인스턴스에서 호출하십시오. (예 : TouchView.setRadius(...) 대신 touchView.setRadius(...))

invalidate은보기의 고정 된 방법이 아니므로 사용자는이를 하나로서 호출 할 수 없습니다. 뷰를 다시 그리도록 요구하는 속성이 변경되면 invalidate 자체가 표시되어야합니다. 반경은 TouchView의 속성 중 하나이므로 setRadius 메서드가 끝나면 invalidate()으로 전화해야합니다. 이렇게하면 활동에 속하지 않은 직접적인 invalidate 통화가 삭제됩니다.

+0

그 정보에 대해 감사드립니다. 당신이 묘사 한 방식은 뷰가 스스로를 업데이트해야하는 방식입니다. 나는 이것을 세 심하게 바꿀 것이다. :) – turtleboy

관련 문제