Android 从不同 class 访问 canvas

Android access canvas from different class

我需要访问我从另一个 class 创建的 canvas。

所以我有一个 class 延伸 LinearLayout 绘图弧。

现在从 main activity 我需要访问这个 canvas 它被绘制并重绘。最好只有一部分。

这里有一些代码被剥离到主要部分。

ArchProgressBar.java(带canvas的那个)

public class ArchProgressBar extends LinearLayout {

    public ArchProgressBar(Context context, AttributeSet attrs) {

    private void init(Context context) {
        this.setWillNotDraw(false);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.arch_progress_bar, this, true);
        this.postInvalidate();
    }

    static void drawMeCircle(int aka) {

    }

    @Override
    public void onDraw(Canvas canvas) {

        int mPaintHex = 0xFFFFFFFF;
        int mPaintColor = Color.argb(100, Color.red(mPaintHex), Color.green(mPaintHex), Color.blue(mPaintHex));

        float left = 295;
        float top = 712;
        float right = 788;
        float bottom = 1208;

        Paint mPaintBackground = new Paint();
        mPaintBackground.setAntiAlias(true);
        mPaintBackground.setStyle(Paint.Style.STROKE);
        mPaintBackground.setStrokeWidth(13);
        mPaintBackground.setColor(mPaintColor);

        RectF mRectF = new RectF(left, top, right, bottom);

        // THIS IS BACKGROUND LINE! draw background line
        canvas.drawArc(mRectF, START_ANGLE, ARCH_LENGTH, false, mPaintBackground);

        int mHourHex = 0xFF00FF00;
        int mHourColor = Color.argb(255, Color.red(mHourHex), Color.green(mHourHex), Color.blue(mHourHex));

        Paint mPaintHours = new Paint();
        mPaintHours.setAntiAlias(true);
        mPaintHours.setStyle(Paint.Style.STROKE);
        mPaintHours.setStrokeWidth(13);
        mPaintHours.setColor(mHourColor);

        RectF mRectH = new RectF(left, top, right, bottom);

        // THIS IS HOUR LINE!draw hour line
        Calendar hCal = Calendar.getInstance();
        int hHour = hCal.get(Calendar.HOUR);
        if(hHour != 0) {
            for(int i=0; i<hHour-1; i++){
                canvas.drawArc(mRectH, START_ANGLE + ARCH_LENGTH + (i*30) +2, ARCH_LENGTH, false, mPaintHours);
            }
        }
    }

HomeActivity.java 主要 activity 应用程序(扩展 Activity

public class HomeActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(Intent.ACTION_TIME_TICK);
        mIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        mIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
        registerReceiver(m_timeChangedReceiver, mIntentFilter);
    }
    //clock thing start
    private final BroadcastReceiver m_timeChangedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
                Calendar hCal = Calendar.getInstance();
                int hHour = hCal.get(Calendar.HOUR);
                ArchProgressBar.drawMeCircle(1);
        }
    };

    public void showApps(View v){
        Intent i = new Intent(this, AppsListActivity.class);
        startActivity(i);
    }
}

现在当 BroadcastRecieved 被触发时,我想访问 ArchProgressBar 的 canvas,删除 hour line(或者如果不可能删除整个内容,只删除那部分) 并在其上重新绘制一些新内容。

如果你正在徘徊 drawMeCircle。这只是我在玩的东西。包括在内以展示我认为它必须如何工作。

您只需更改视图对象中的一些值并调用 invalidate() 即可获得您需要的内容。这将尽快重绘 canvas 。关于你的代码,我建议以这种方式修改它(假设你的视图有一个 id = @+id/arch_progress_bar)

HomeActivity

private final BroadcastReceiver m_timeChangedReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        Calendar hCal = Calendar.getInstance();
        int hHour = hCal.get(Calendar.HOUR);
        ArchProgressBar bar = (ArchProgressBar) findViewById(R.id.arch_progress_bar);
        if (bar != null) {
            bar.drawMeCircle(1);
        }
    }
};

// remember to unregister the broadcast receiver in your onDestroy()
// as further optimization, you can also move the findViewById inside your onCreate(), so you don't have to repeat it for every broadcast you get

ArchProgressBar

pubic void drawMeCircle(int aka) {
     // your business logic
     invalidate();
}   // Remove the static keyword, it's not necessary

最后考虑:由于显示旋转,您应该注意 activity 娱乐。要处理这种情况,您应该在 onSaveInstanceState() activity 回调期间保存从广播接收器获得的值(本例中为 1?),通过作为 onCreate 参数获得的包检索它并将其重新设置为您的视图。