多次绘制画布 - 最佳实践

时间:2017-12-14 14:56:22

标签: android android-animation android-canvas

我仍在寻找在画布上多次画画的正确方法。

希望的结果: ImageView设置为可见,显示第一个文本,然后是第二个而不是第一个,最后是第三个而不是第二个。每个文本都可见半秒

想法:在每个文字后使用setColor(Color.WHITE)绘制画布,使用synchronized块设置backgroundcolor和text,使用invalidate()和自定义draw()方法

我尝试了不同的方法,这是我的代码的当前版本: initializeStimulus() - 在我的服务的onCreate()中调用

        private void initializeStimulus(String stimulus) {

            windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
            stimulusOverlay = new CustomImageView(this);
            stimulusOverlay.setBackgroundColor(getResources().getColor(R.color.background_stimulus));
            stimulusOverlay.setVisibility(View.VISIBLE);

            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT
            );

            // Position of stimuli in relation to screen size / 2
            Point displaySize = new Point();
            windowManager.getDefaultDisplay().getRealSize(displaySize);
            int width = displaySize.x;
            int height = displaySize.y;
            params.x = 0;
            params.y = 0;
            windowManager.addView(stimulusOverlay, params);

            imageBitmap = Bitmap.createBitmap((width/3)*2, height/5, Bitmap.Config.ARGB_8888);
            p = new Paint();

            Canvas canvas = new Canvas(imageBitmap);
            p.setColor(Color.BLACK);
            Typeface non_proportional_font = Typeface.createFromAsset(getAssets(), "fonts/luximr.ttf");
            p.setTypeface(non_proportional_font);
            float scale = getResources().getDisplayMetrics().density;
            p.setTextSize(40 * scale);

            fillTextPathArray();

            stimulusOverlay.setImageBitmap(imageBitmap);

            stimulusOverlay.draw(canvas);
    }


    private void fillTextPathArray(){

        mTextPaths = new ArrayList<Path>(VOC_COUNT);
        String[] text = new String[VOC_COUNT];

        String stimulus = getStimulusFromPref(positionStimulus);
        int stimulusLength = stimulus.length();
        String masking = String.format("%0" + stimulusLength + "d", 0).replace('0', 'X');

        text[0] = masking;
        text[1] = stimulus;
        text[2] = masking;

        for (int i = 0; i < text.length; i++) {
            Path path = new Path();
            p.getTextPath(text[i], 0, masking.length(), imageBitmap.getWidth()/4, (imageBitmap.getHeight()/3)*2, path);
            path.close(); // not required on 2.2/2.3 devices
            mTextPaths.add(path);
        }
    }

这个函数创建了一个路径的ArrayList,我需要以正确的顺序显示它。因此,最后,用户将能够看到我的画布从第一个文本更改为第二个文本到第三个文本。

我开始使用“重绘整个视图”或“在旧文本上使用backgroundcolor绘制框”(Android Canvas Drawing Text and Change Text afterwards)等提示,因为无法显示画布图。没有为我工作。 最大的问题仍然存在:代码贯穿始终,一切都将在一个画布上显示,一个在另一个画布上方。 AND:像while循环或Thread.sleep(500)这样的时间延迟对画布没有任何影响。结果是一样的:代码正在运行 - 给定的时间延迟 - 而在结尾一切都被绘制,而不是一步一步(第一,第二,第三)。 我甚至尝试用不同的方法绘制每个文本。

所以我尝试实现每个给定的新Canvas,新的Paint甚至是新的View - 没有任何改变。最后,所有东西都被抽取而不是一步一步。

目前我有自定义ImageView(CustomImageView),我在使用同步块时使用invalidate()方法。

    private class CustomImageView extends AppCompatImageView {

        private boolean stimulusVisible = false;
        private int countStimuli = 0;

        public CustomImageView(Context context) {
            super(context);
        }

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

            if (!stimulusVisible) {
                Object lock = new Object();
                synchronized (lock) {
                    canvas.drawPath(mTextPaths.get(countStimuli), p);
                    stimulusVisible = true;
                    countStimuli++;
                }
            } else {
                long startTime = System.currentTimeMillis();
                while((System.currentTimeMillis()-startTime) < 500){}
                canvas.drawColor(Color.CYAN);
                stimulusVisible = false;
            }
            invalidate();
        }
    }

while循环应该停止所有内容半秒钟。

我真的希望你的支持。 有没有更好的方法来实现这个? 我错过了什么吗?我虽然invalidate()会重绘画布,但它没有影响。我现在试了2天,请帮忙。

0 个答案:

没有答案