অ্যান্ড্রয়েড, ক্যানভাস: কোনও পৃষ্ঠতলটিতে থাকা ক্যানভাস (= বিটম্যাপস) কীভাবে সাফ করব (এর সামগ্রীগুলি মুছব)?


96

একটি সহজ গেম করার জন্য, আমি একটি টেমপ্লেট ব্যবহার করেছি যা বিটম্যাপগুলির সাথে এর মতো ক্যানভাস আঁকে:

private void doDraw(Canvas canvas) {
    for (int i=0;i<8;i++)
        for (int j=0;j<9;j++)
            for (int k=0;k<7;k++)   {
    canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }

(ক্যানভাসটি "রান ()" এ সংজ্ঞায়িত করা হয়েছে / সারফেসভিউ একটি গেমথ্রেডে বাস করে))

আমার প্রথম প্রশ্নটি হল আমি কীভাবে একটি নতুন বিন্যাসের জন্য পুরো ক্যানভাসটি সাফ (বা পুনরায় আঁকা) করব ?
দ্বিতীয়ত, আমি কীভাবে পর্দার একটি অংশ আপডেট করতে পারি?

// This is the routine that calls "doDraw":
public void run() {
    while (mRun) {
        Canvas c = null;
        try {
            c = mSurfaceHolder.lockCanvas(null);
            synchronized (mSurfaceHolder) {
                if (mMode == STATE_RUNNING) 
                    updateGame();
                doDraw(c);          }
        } finally {
            if (c != null) {
                mSurfaceHolder.unlockCanvasAndPost(c);  }   }   }       }

উত্তর:


78

কীভাবে আমি নতুন লেআউটের জন্য পুরো ক্যানভাস (= গেমটি চেষ্টা করে) পরিষ্কার করব (বা পুনরায় চিত্রিত করব)?

কেবল কল করুন Canvas.drawColor(Color.BLACK)বা আপনি যে রঙটি দিয়ে সাফ করতে চান তা করুন Canvas

এবং: আমি কীভাবে পর্দার একটি অংশ আপডেট করতে পারি?

স্ক্রিন আপডেট করার সময় অ্যান্ড্রয়েড ওএস প্রতিটি পিক্সেল পুনরায় আঁকছে বলে কোনও "পর্দার অংশ" আপডেট করার মতো কোনও পদ্ধতি নেই। তবে, যখন আপনি নিজের উপর পুরানো অঙ্কনগুলি সাফ করছেন না Canvas, তখন পুরানো আঁকাগুলি তলানীতে রয়েছে এবং এটি সম্ভবত পর্দার "মাত্র একটি অংশ আপডেট করার" এক উপায়।

সুতরাং, আপনি যদি "স্ক্রিনের কোনও অংশ আপডেট করতে চান", কেবল কল করার Canvas.drawColor()পদ্ধতিটি এড়িয়ে চলুন ।


4
না, যদি আপনি পৃষ্ঠের প্রতিটি পিক্সেলটি আঁকেন না তবে আপনি খুব অদ্ভুত ফলাফল পাবেন (কারণ ডাবল বাফারিং পয়েন্টারগুলিকে অদলবদল করে অর্জিত হয়, সুতরাং যে অংশগুলিতে আপনি আঁকেন না সেখানে আপনি দেখতে পাবেন না যে সেখানে আগে কী ছিল)। আপনি আছে প্রতিটি পুনরাবৃত্তির এ পৃষ্ঠ প্রতিটি পিক্সেল পুনরায় আঁকুন।
গিলিয়াম ব্রুনারি

4
@ ভিক্টর ল্যান’র: আপনি যদি ফোন করেন mSurfaceHolder.unlockCanvasAndPost(c)এবং তারপরে c = mSurfaceHolder.lockCanvas(null), তবে নতুনটিতে আগেরটির cমতো জিনিস থাকে না c। আপনি কোনও সার্ফেসভিউয়ের কেবলমাত্র একটি অংশ আপডেট করতে পারবেন না, এটিই ওপি আমার অনুমান হিসাবে জিজ্ঞাসা করেছিল।
গিলিয়াম ব্রুনেরি

4
@ গুইলাউম ব্রুনারি: সত্য, তবে সব কিছু নয়। আমি লিখেছিলে আপনি পর্দার একটি অংশ আপডেট করতে পারবেন না। তবে আপনি স্ক্রিনে পুরানো অঙ্কন রাখতে পারেন, যা কেবল "স্ক্রিনের একটি অংশ আপডেট করুন" এর প্রভাব ফেলবে will একটি নমুনা অ্যাপ্লিকেশন এ নিজে চেষ্টা করুন। Canvasপুরানো অঙ্কন রাখে।
রোকলাই

4
নিজের প্রতি লজ্জা !!! গেম শুরু করার সময় আমি কেবলমাত্র একবারেই আমার অ্যারে শুরু করি না একটানা পুনরায় শুরু হয় - সুতরাং সমস্ত পুরানো টুকরা "অনস্ক্রিন" থেকে যায় - এগুলি কেবল নতুন করে আঁকানো হয়েছিল !!! আমি আমার "বোবা" জন্য খুব দুঃখিত! আপনাদের দুজনকেই ধন্যবাদ !!!
samClem

4
তবে এটি সম্ভবত কারণ লাইভ ওয়ালপেপারগুলি নিয়মিত সারফেসভিউয়ের মতো একইভাবে কাজ করে না। যাইহোক, @ স্যামক্লেম: সর্বদা প্রতিটি ফ্রেমে ক্যানভাসের প্রতিটি পিক্সেল পুনরায় আঁকুন (নথিতে বলা আছে) বা আপনার কাছে অদ্ভুত ঝলকানি হবে।
গিলিয়াম ব্রুনারি

280

পোর্টারডাফ ক্লিয়ার মোডের সাথে স্বচ্ছ রঙ আঁকুন আমি যা চাইছিলাম তা চালিত করে।

Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

4
এটি কাজ করা উচিত, তবে Bitmap#eraseColor(Color.TRANSPARENT)নীচে HeMac এর উত্তর হিসাবে, 4.4 (কমপক্ষে N7.2 এর উপর) ব্যবহারে বুগ করা হয়েছে বলে মনে হচ্ছে ।
এনএমআর

4
আসলে, Color.TRANSPARENTঅপ্রয়োজনীয়। বিটম্যাপের PorterDuff.Mode.CLEARজন্য একেবারে যথেষ্ট, ARGB_8888যার অর্থ আলফা এবং রঙ সেট করা [0, 0]। আর একটি উপায় Color.TRANSPARENTসঙ্গে ব্যবহার করা হয় PorterDuff.Mode.SRC
jisli

4
এটি আমার পক্ষে স্বচ্ছ পরিবর্তে একটি ফাঁকা পৃষ্ঠ ছাড়ার জন্য কাজ করছে না
পল্লব বোহারা

31

এটি গুগল গ্রুপগুলিতে পাওয়া গেছে এবং এটি আমার পক্ষে কাজ করেছে ..

Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, clearPaint); 

এটি বিটম্যাপ সেট রাখার সময় অঙ্কনগুলি আয়তক্ষেত্রগুলি ইত্যাদি সরিয়ে দেয় ..


4
এটি আমাকে একটি কালো অঞ্চল দেয় - এর পিছনে থাকা বিটম্যাপটি নয় :(
স্লট

এটি পরিষ্কার হয়ে গেছে, তবে বিটম্যাপটিও আপনি যে বলেছিলেন তার বিপরীতেও সরানো হবে।
ওমর রেহমান

স্ট্যাকওভারফ্লো . com/ প্রশ্নস / 69 69 19 85 85৮৫ / এ কীভাবে ক্যানভাসের কিছু আয়তক্ষেত্রে বিটম্যাপের একটি আয়তক্ষেত্র আঁকবেন তা ব্যাখ্যা করা হয়েছে। একটি আয়তক্ষেত্রে একটি চিত্র পরিবর্তন করুন এভাবে কাজ করে: পূর্ববর্তী বিষয়বস্তুগুলি শিখুন, নতুন চিত্র আঁকুন
মার্টিন

18

পাথ শ্রেণির পুনরায় সেট করার পদ্ধতিটি ব্যবহার করুন

Path.reset();

আপনি যদি কোনও পথ ব্যবহার করেন তবে এটি সত্যিই সেরা উত্তর। অন্যগুলি ব্যবহারকারীকে একটি কালো পর্দা দিয়ে ছেড়ে দিতে পারে। ধন্যবাদ
j2emanue 16'19

18

আমি @ মুভিস্ট্রি এর উত্তর চেষ্টা করেছি:

canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

তবে এটি আমার পক্ষে কাজ করে না।

আমার কাছে সমাধানটি ছিল:

canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);

কারও কারওর একই সমস্যা হতে পারে।


4
স্বচ্ছতার সাথে গুণ করা উত্তর is অন্যথায় এটি কিছু ডিভাইসে কালো রঙিন হয়ে যেতে পারে।
আন্দ্রেয়াস রুডল্ফ

12
mBitmap.eraseColor(Color.TRANSPARENT);

canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

4
এটি সবচেয়ে সঠিক কিভাবে? আপনি যখন শুধু রঙিন আঁকতে পারেন তখন কেন একটি বিটম্যাপ ব্যবহার করবেন?
রিচিএইচ এইচ

যদিও এটি মূল পোস্টারের জন্য কাজ না করে (বিটম্যাপে তাদের অগত্যা অ্যাক্সেস নেই) এটি উপলভ্য হলে বিটম্যাপের বিষয়বস্তু সাফ করার জন্য অবশ্যই এটি কার্যকর। এই ক্ষেত্রে, শুধুমাত্র প্রথম লাইন প্রয়োজন। দরকারী কৌশল, +1
কোডগুলিতে

4

ক্লাস কনস্ট্রাক্টর প্রসারিত পর্যালোচনাতে কোডের নীচে পেস্ট করুন .............

কনস্ট্রাক্টর কোডিং

    SurfaceHolder holder = getHolder();
    holder.addCallback(this);

    SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview);
    sur.setZOrderOnTop(true);    // necessary
    holder = sur.getHolder();
    holder.setFormat(PixelFormat.TRANSPARENT);

এক্সএমএল কোডিং

    <com.welcome.panelview.PanelViewWelcomeScreen
        android:id="@+id/one"
        android:layout_width="600px"
        android:layout_height="312px"
        android:layout_gravity="center"
        android:layout_marginTop="10px"
        android:background="@drawable/welcome" />

উপরের কোড চেষ্টা করুন ...


হোল্ডার.সেট ফোর্ম্যাট (পিক্সেলফর্ম্যাট.ট্রান্স্পারেন্ট); এটা আমার জন্য কাজ করে.
অ্যারন লি

3

এখানে সর্বনিম্ন উদাহরণের কোডটি দেখানো হচ্ছে যে আপনাকে সর্বদা প্রতিটি ফ্রেমে ক্যানভাসের প্রতিটি পিক্সেলকে আবার আঁকতে হয়।

এই ক্রিয়াকলাপটি আগে স্ক্রিনটি সাফ না করে সারফেসভিউয়ে প্রতি সেকেন্ডে একটি নতুন বিটম্যাপ আঁকে। আপনি যদি এটি পরীক্ষা করেন তবে আপনি দেখতে পাবেন যে বিটম্যাপটি সর্বদা একই বাফারে লেখা থাকে না এবং স্ক্রিনটি দুটি বাফারের মধ্যে বিকল্প হবে।

আমি এটি আমার ফোনে (নেক্সাস এস, অ্যান্ড্রয়েড ২.৩.৩) এবং এমুলেটরটিতে (অ্যান্ড্রয়েড ২.২) পরীক্ষা করে দেখেছি।

public class TestCanvas extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new TestView(this));
    }
}

class TestView extends SurfaceView implements SurfaceHolder.Callback {

    private TestThread mThread;
    private int mWidth;
    private int mHeight;
    private Bitmap mBitmap;
    private SurfaceHolder mSurfaceHolder;

    public TestView(Context context) {
        super(context);
        mThread = new TestThread();
        mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        mWidth = width;
        mHeight = height;
        mThread.start();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (mThread != null && mThread.isAlive())
            mThread.interrupt();
    }

    class TestThread extends Thread {
        @Override
        public void run() {
            while (!isInterrupted()) {
                Canvas c = null;
                try {
                    c = mSurfaceHolder.lockCanvas(null);
                    synchronized (mSurfaceHolder) {
                        c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null);
                    }
                } finally {
                    if (c != null)
                        mSurfaceHolder.unlockCanvasAndPost(c);
                }

                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    interrupt();
                }
            }
        }   
    }
}

ঠিক আছে, মনে হচ্ছে আপনি ভুল হয়ে গেছেন, আমার স্ক্রিন ক্যাপচারটি এখানে দেখুন: img12.imageshack.us/i/devicey.png/# আপনি যখন এক সেকেন্ডের মতো বিলম্ব যুক্ত করেছেন তখন ডাবল বাফারিং বেশি লক্ষ্য করা যায়, তবে (!) স্ক্রিনে এখনও আগের অঙ্কন রয়েছে। এছাড়াও, আপনার কোডটি ভুল: এটি হওয়া উচিত SurfaceHolder.Callback, কেবল নয় Callback
রোকলাই

4
আমি মনে করি আপনি কী বলতে চাইছেন তা বুঝতে পারছেন না। এক যেটি আশা করতে পারে তা হ'ল ফ্রেম এন এবং ফ্রেম এন + 1 এর মধ্যে পার্থক্য হ'ল আরও একটি বিটম্যাপ রয়েছে। তবে এটি সম্পূর্ণরূপে ভুল, ফ্রেম এন এবং ফ্রেম এন + 2 এর মধ্যে আরও একটি বিটম্যাপ রয়েছে তবে ফ্রেম এন এবং ফ্রেম এন + 1 সম্পূর্ণ অপ্রাসঙ্গিক এমনকি আমি কেবল একটি বিটম্যাপ যুক্ত করলেও।
গিলিয়াম ব্রুনারি

না, আমি আপনাকে পুরোপুরি বুঝতে পেরেছি। তবে, আপনি যেমন দেখেন, আপনার কোডটি কাজ করে না। কিছুক্ষণ পরে, পর্দা আইকন দিয়ে পূর্ণ। সুতরাং, আমরা Canvasপুরো স্ক্রিনটি পুরোপুরি পুনরায় আঁকতে চাইলে আমাদের তা সাফ করা দরকার । এটি "পূর্ববর্তী অঙ্কনগুলি" সম্পর্কে আমার বক্তব্যকে সত্য করে তোলে। Canvasপূর্ববর্তী অঙ্কন রাখে।
রোকলাই

4
হ্যাঁ যদি আপনি চান, একটি Canvasপূর্ববর্তী অঙ্কন রাখে। তবে এটি সম্পূর্ণ অকেজো, সমস্যাটি হ'ল আপনি যখন ব্যবহার lockCanvas()করবেন তখন আপনি জানেন না যে এই "পূর্ববর্তী অঙ্কন" কী, এবং সেগুলি সম্পর্কে কিছুই অনুমান করতে পারবেন না। সম্ভবত যদি একই আকারের একটি সারফেসভিউ সহ দুটি ক্রিয়াকলাপ হয় তবে তারা একই ক্যানভাসটি ভাগ করে নেবে। সম্ভবত আপনি এটিতে এলোমেলো বাইট সহ অবিচ্ছিন্ন র‌্যামের একটি অংশ পেয়েছেন। সম্ভবত যে ক্যানভাসে সবসময় গুগল লোগো লেখা থাকে। আপনি জানতে পারবেন না। যে কোনও অ্যাপ্লিকেশন যা প্রতি পিক্সেলের পরে অঙ্কন করছে না lockCanvas(null)তা নষ্ট হয়ে গেছে।
গিলিয়াম ব্রুনারি

4
আমি আপনার পোস্ট জুড়ে আসার পরে @ গুইলাউম ব্রুনেরি 2.5 বছর পরে অফিসিয়াল অ্যান্ড্রয়েড ডকুমেন্টেশনগুলি "প্রতিটি পিক্সেল অঙ্কন" সম্পর্কিত আপনার পরামর্শকে সমর্থন করে। কেবলমাত্র একটি কেস রয়েছে যেখানে ক্যানভাসের একটি অংশ এখনও লকক্যানভাস () এর সাথে পরবর্তী কল সহ সেখানে উপস্থিত থাকার নিশ্চয়তা দেয়। সারফেসহোল্ডার এবং এর দুটি লকক্যানভাস () পদ্ধতিগুলির জন্য অ্যান্ড্রয়েড ডকুমেন্টেশন দেখুন। বিকাশকারী.অ্যান্ড্রয়েড.
com

3

আমার জন্য কল করা Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)বা এর মতো অন্য কিছু কেবল তখন আমি স্ক্রিনটি স্পর্শ করার পরে কাজ করবে। সুতরাং আমি উপরের কোডের লাইনটি কল করব তবে আমি তখন স্ক্রিনটি স্পর্শ করার পরে পর্দাটি পরিষ্কার হবে। সুতরাং আমার জন্য যা কাজ হয়েছিল তা হল কলটি যা invalidate()তারপরে init()দর্শনের সূচনা করার জন্য সৃষ্টির সময় বলা হয়েছিল।

private void init() {
    setFocusable(true);
    setFocusableInTouchMode(true);
    setOnTouchListener(this);

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(6);

    mCanvas = new Canvas();
    mPaths = new LinkedList<>();

    addNewPath();
}

3
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);

4
আপনার কোডটি কীভাবে সমস্যার সমাধান করে তার একটি ব্যাখ্যা যুক্ত করুন। এটি নিম্নমানের পোস্ট হিসাবে পতাকাঙ্কিত করা হয়েছে - পর্যালোচনা থেকে
সুরজ রাও

1

জাভা অ্যান্ড্রয়েডে ক্যানভাসে মুছে ফেলা একইভাবে গ্লোবাল কম্পোজিটঅপেশনের সাথে জাভাস্ক্রিপ্টের মাধ্যমে এইচটিএমএল ক্যানভাস মুছে ফেলা। যুক্তিও ছিল একই রকম।

আপনি DST_OUT (গন্তব্য আউট) যুক্তি চয়ন করবেন।

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

দ্রষ্টব্য: DST_OUT আরও কার্যকর কারণ এটি রঙের 50% আলফা থাকলে এটি 50% মুছতে পারে। সুতরাং, সম্পূর্ণ স্বচ্ছ থেকে সাফ করার জন্য, বর্ণের আলফা অবশ্যই 100% হওয়া উচিত। পেইন্ট.সেট কলার প্রয়োগ করুন (রঙ। ডাব্লুএইচআইটি) প্রস্তাবিত। এবং নিশ্চিত হয়ে নিন যে ক্যানভাস চিত্রের ফর্ম্যাটটি ছিল RGBA_8888।

মোছা হয়ে যাওয়ার পরে, SRC_OVER (উত্স ওভার) দিয়ে স্বাভাবিক অঙ্কনে ফিরে যান।

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));

আক্ষরিকভাবে ছোট অঞ্চল প্রদর্শন আপডেট করার জন্য গ্রাফিক হার্ডওয়্যার অ্যাক্সেস করতে হবে এবং এটি সমর্থিত নয় maybe

সর্বাধিক পারফরম্যান্সের জন্য সবচেয়ে কাছাকাছি হ'ল মাল্টি ইমেজ স্তর ব্যবহার করা।


আপনি কি আমাকে এখানে সাহায্য করতে পারেন? আপনার একমাত্র সমাধান যা আমার মামলার পক্ষে কাজ করেছে তাই আমি ভোট দিয়েছি, সামান্য সমস্যা আছে যা সমাধান করা দরকার
হামজা খান

আমি পৃষ্ঠতলের ধারক সহ ক্যানভাস ব্যবহার করছি, তাই আমি ক্যানভাস পরিষ্কার করার জন্য এটি করি (পৃষ্ঠতল ধারক থেকে নেওয়া ক্যানভাস): পেইন্ট !!। ! .নলকক্যানভাসঅ্যান্ডপোস্ট (ক্যানভাস) তারপরে এটি পুনরায় আঁকতে সক্ষম হবেন: পেইন্ট !!। সেটএক্সফর্মোড (পোর্টারডাফএক্সফর্মমোড (পোর্টারডাফ.মোড.এসআরসি)) ক্যানভাস !! এইভাবে ক্যানভাস সাফ করার পরে, যখন আমি ক্যানভাসের উপর একটি বিটম্যাপ আঁকি, এটি রঙিন একটি ঝলক পরে টানা হয়, যা বিরক্তিকর, আপনি কি আমাকে এখানে পথ দেখাতে পারেন? @ এফএনএইচও
হামজা খান

@ হামজা খান আপনি কি এসআরসি_ওভার দিয়ে চেষ্টা করেছেন? কারণ SRC_OVER ডিফল্ট স্বাভাবিক। এসআরসি যুক্তি পুরানো পিক্সেল ডেটা ওভাররাইট করা হয়, এটি আলফাকে প্রতিস্থাপন করে!
phnghue


0

কোনও ক্রিয়াকলাপের অন্বেজ () এ দর্শনটি সরিয়ে চেষ্টা করুন এবং পুনরায় চালু করুন ()

লেআউটআউ অ্যাডেড ইয়োরভিউ.এডিডিভিউ (আপনার কাস্টমভিউ); লেআউটআউ অ্যাডেড ইয়োরভিউ.রেমভভিউ (আপনার কাস্টমভিউ);

যে মুহুর্তে আপনি আপনার ভিউ যুক্ত করবেন, অন ড্র () পদ্ধতিটি কল হবে get

আপনার কাস্টমভিউ, একটি শ্রেণি যা ভিউ ক্লাসটি প্রসারিত করে।


0

আমার ক্ষেত্রে, আমি আমার ক্যানভাসকে লিনিয়ারলেটে আঁকছি। আবার পরিষ্কার ও পুনরায় আঁকতে:

    LinearLayout linearLayout = findViewById(R.id.myCanvas);
    linearLayout.removeAllViews();

এবং তারপরে, আমি ক্লাসটিকে নতুন মান সহ কল ​​করি:

    Lienzo fondo = new Lienzo(this,items);
    linearLayout.addView(fondo);

এই ক্লাস লিয়েনজো:

class Lienzo extends View {
    Paint paint;
    RectF contenedor;
    Path path;
    ArrayList<Items>elementos;

    public Lienzo(Context context,ArrayList<Items> elementos) {
        super(context);
        this.elementos=elementos;
        init();
    }

    private void init() {
        path=new Path();
        paint = new Paint();
        contenedor = new RectF();
        paint.setStyle(Paint.Style.FILL);
    }


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

        contenedor.left = oneValue;
        contenedor.top = anotherValue;
        contenedor.right = anotherValue;
        contenedor.bottom = anotherValue;

        float angulo = -90; //starts drawing at 12 o'clock
        //total= sum of all element values
        for (int i=0;i<elementos.size();i++){
            if (elementos.get(i).angulo!=0 && elementos.get(i).visible){
                paint.setColor(elementos.get(i).backColor);
                canvas.drawArc(contenedor,angulo,(float)(elementos.get(i).value*360)/total,true,paint);

                angulo+=(float)(elementos.get(i).value*360)/total;
            }
        } //for example
    }
}

0

নিম্নলিখিত পদ্ধতির সাহায্যে আপনি পুরো ক্যানভাস বা এর একটি অংশ পরিষ্কার করতে পারেন। পোর্টারডাফ.মোড.ক্লেয়ার হার্ডওয়্যার এক্সিলারেশনটির সাথে কাজ করে না এবং শেষ পর্যন্ত কল করুন কারণ আমরা পদ্ধতিটিকে ওভাররাইড করি তাই
দয়া করে হার্ডওয়্যার ত্বরণ অক্ষম করতে ভুলবেন না ।setWillNotDraw(false)onDraw

//view's constructor
setWillNotDraw(false);
setLayerType(LAYER_TYPE_SOFTWARE, null);

//view's onDraw
Paint TransparentPaint = new Paint();
TransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, TransparentPaint); 

এটি কাজ, তবে এর পরে আমার আঁকতে আরও বেশি দৃশ্যমান হয় না
ডায়নো ক্রিস

4
@ ডায়নক্রিস সম্ভবত আপনি একই পেইন্ট অবজেক্টটি ব্যবহার করছেন !? একটি নতুন দিয়ে চেষ্টা করুন, এবং দয়া করে upvote ভুলবেন না।
ucMedia

এটি আমার কোড পেস্টবিন.com/জিডাব্লুবিডিটিইউপি 5 যখন আমি আবার আঁকতে চেষ্টা করি তখন আমি লাইনগুলিকে আরও নিখরচায় দেখতে পাচ্ছি না। তবে ক্যানভাস পরিষ্কার is
ডায়নো ক্রিস

4
দয়া করে পরিবর্তন @DynoCris LAYER_TYPE_HARDWAREকরতেLAYER_TYPE_SOFTWARE
ucMedia

4
ওহ, সত্যিই, এটি আমার ভুল তবে এটি আমাকে যাইহোক নিখরচায় সহায়তা করেনি।
ডায়নো ক্রিস

-1

আপনার সম্পূর্ণ প্রয়োজনীয়তা, কীভাবে পুরো ক্যানভাস সাফ বা পুনরায় আঁকবেন - উত্তর - কালো রঙের বর্ণ বা আপনার নির্দিষ্ট করে যা কিছু নির্দিষ্ট রয়েছে তা দিয়ে পর্দা সাফ করার জন্য ক্যানভাস.ড্রোলাকলার (color.Black) পদ্ধতিটি ব্যবহার করুন।

আপনার দ্বিতীয় প্রয়োজনীয়তা, কীভাবে পর্দার অংশ আপডেট করবেন - উত্তর - উদাহরণস্বরূপ আপনি যদি অন্য সমস্ত জিনিসকে পর্দায় অপরিবর্তিত রাখতে চান তবে স্ক্রিনের একটি ছোট অঞ্চলে একটি পূর্ণসংখ্যার (কাউন্টার বলুন) দেখান যা প্রতি পাঁচ সেকেন্ড পরে বৃদ্ধি পায়। তারপরে বাম উপরের ডান নীচে এবং পেইন্টটি উল্লেখ করে সেই ছোট অঞ্চলটি আঁকতে ক্যানভাস.ড্রাক্ট পদ্ধতি ব্যবহার করুন। তারপরে আপনার পাল্টা মানটি গণনা করুন (5 সেকেন্ডের জন্য পোস্টড্যালয়েড ইত্যাদি ব্যবহার করে, হ্যান্ডেলআরপোস্টডেলিডের মতো (রান্নেবল_অবজেক্ট, 5000);), এটি পাঠ্য স্ট্রিংয়ে রূপান্তর করুন, এই ছোট্ট রেক্টরে x এবং y স্থানাঙ্কটি গুনুন এবং পরিবর্তনটি প্রদর্শনের জন্য পাঠ্য দৃশ্যের ব্যবহার করুন পাল্টা মান।


-1

ক্যানভাসটি সাফ করার জন্য আমাকে একটি পৃথক অঙ্কন পাস ব্যবহার করতে হয়েছিল (লক, অঙ্কন এবং আনলক):

Canvas canvas = null;
try {
    canvas = holder.lockCanvas();
    if (canvas == null) {
        // exit drawing thread
        break;
    }
    canvas.drawColor(colorToClearFromCanvas, PorterDuff.Mode.CLEAR);
} finally {
    if (canvas != null) {
        holder.unlockCanvasAndPost(canvas);
    }
}

-3

শুধু কল

ক্যানভাস.ড্রোলার কালার


16
এটি কাজ করে না কারণ এটি কেবল বর্তমান ক্লিপের শীর্ষে স্বচ্ছতা এনে দেবে ... কার্যকরভাবে কিছুই করা যায় না। তবে, আকাঙ্ক্ষিত ফল অর্জন করা পোর্টার-ডাফের ট্রান্সফার মোড পরিবর্তন করতে পারেন: Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)। যদি আমি ভুল না হয়ে থাকি তবে রঙটি আসলে কিছু হতে পারে (ট্রান্সপারেন্ট হতে হবে না) কারণ PorterDuff.Mode.CLEARকেবল বর্তমান ক্লিপটি সাফ হয়ে যাবে (ক্যানভাসের কোনও গর্ত ঘুষি দেওয়ার মতো)।
ashughes
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.