বহু-গ্রেডিয়েন্ট আকার


177

আমি একটি চিত্র তৈরি করতে চাই যা নীচের চিত্রের মতো:

বিকল্প পাঠ

রঙ 1 থেকে রঙ 2 থেকে উপরের অর্ধেক গ্রেডিয়েন্টগুলি লক্ষ্য করুন, তবে একটি নীচের অর্ধেকটি গ্রেডিয়েন্ট 3 থেকে বর্ণ 4 বর্ণে রয়েছে I দুটি অর্ধেক এবং 2 টি বিভিন্ন গ্রেডিয়েন্ট দিয়ে 1 আকৃতি তৈরি করুন।

কোন ধারনা?


আরো দেখুন stackoverflow.com/a/26270218/185022
AZ_

উত্তর:


383

আমি মনে করি না আপনি এটি এক্সএমএলে করতে পারেন (কমপক্ষে অ্যান্ড্রয়েডে নয়) তবে আমি এখানে পোস্ট করা একটি ভাল সমাধান পেয়েছি যা দেখে মনে হচ্ছে এটি দুর্দান্ত সাহায্য হবে!

ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
    @Override
    public Shader resize(int width, int height) {
        LinearGradient lg = new LinearGradient(0, 0, width, height,
            new int[]{Color.GREEN, Color.GREEN, Color.WHITE, Color.WHITE},
            new float[]{0,0.5f,.55f,1}, Shader.TileMode.REPEAT);
        return lg;
    }
};

PaintDrawable p=new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);

মূলত, ইন্ট অ্যারে আপনাকে একাধিক রঙের স্টপগুলি নির্বাচন করতে দেয় এবং নীচের ফ্লোট অ্যারেটি যেখানে স্টপগুলি অবস্থিত তা নির্ধারণ করে (0 থেকে 1 পর্যন্ত)। তারপরে আপনি যেমনটি বলেছিলেন ঠিক এটি স্ট্যান্ডার্ড ড্রয়যোগ্য হিসাবে ব্যবহার করতে পারেন।

সম্পাদনা: আপনি আপনার দৃশ্যে এটি কীভাবে ব্যবহার করতে পারেন তা এখানে। ধরা যাক আপনার মতো এক্সএমএলে একটি বোতাম সংজ্ঞায়িত হয়েছে:

<Button
    android:id="@+id/thebutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Press Me!"
    />

তারপরে আপনি আপনার অনক্রিট () পদ্ধতিতে এরকম কিছু রেখেছিলেন:

Button theButton = (Button)findViewById(R.id.thebutton);
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
    @Override
    public Shader resize(int width, int height) {
        LinearGradient lg = new LinearGradient(0, 0, 0, theButton.getHeight(),
            new int[] { 
                Color.LIGHT_GREEN, 
                Color.WHITE, 
                Color.MID_GREEN, 
                Color.DARK_GREEN }, //substitute the correct colors for these
            new float[] {
                0, 0.45f, 0.55f, 1 },
            Shader.TileMode.REPEAT);
         return lg;
    }
};
PaintDrawable p = new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
theButton.setBackground((Drawable)p);

আমি এই মুহুর্তে এটি পরীক্ষা করতে পারছি না, এটি আমার মাথা থেকে কোড, তবে মূলত কেবল প্রতিস্থাপন করুন বা আপনার প্রয়োজনীয় রঙগুলির জন্য স্টপগুলি যুক্ত করুন। মূলত, আমার উদাহরণস্বরূপ, আপনি হালকা সবুজ দিয়ে শুরু করবেন, কেন্দ্রের সামান্য সাদা হয়ে যাওয়া (কঠোর পরিবর্তনের পরিবর্তে ফেইড দিতে), 45% থেকে 55% এর মধ্যে সাদা থেকে মাঝ সবুজ হয়ে যাওয়া, তারপর থেকে বিবর্ণ 55% থেকে শেষ অবধি মাঝ সবুজ থেকে গা dark় সবুজ। এটি আপনার আকৃতিটির মতো দেখতে ঠিক ঠিক দেখাবে না (এখনই আমার কাছে এই রঙগুলির পরীক্ষার কোনও উপায় নেই) তবে আপনি নিজের উদাহরণটি প্রতিলিপি করতে এটি পরিবর্তন করতে পারেন।

সম্পাদনা করুন: এছাড়াও, 0, 0, 0, theButton.getHeight()গ্রেডিয়েন্টের x0, y0, x1, y1 স্থানাঙ্ককে বোঝায়। সুতরাং মূলত, এটি x = 0 (বাম পাশ), y = 0 (শীর্ষ) থেকে শুরু হয় এবং x = 0 পর্যন্ত প্রসারিত হয় (আমরা উল্লম্ব গ্রেডিয়েন্ট চাই, সুতরাং বাম থেকে ডান কোণটি প্রয়োজনীয় নয়), y = উচ্চতা বোতাম সুতরাং গ্রেডিয়েন্টটি বোতামের শীর্ষ থেকে বোতামের নীচে 90 ডিগ্রি কোণে যায় goes

সম্পাদনা: ঠিক আছে, তাই আমার আরও একটি ধারণা আছে যা কাজ করে, হাহা। এই মুহুর্তে এটি এক্সএমএলে কাজ করে তবে জাভাতেও আকারের জন্য এটি কার্যকর হবে। এটি একধরনের জটিল, এবং আমি কল্পনা করেছি যে এটি একটি একক আকারে সরল করার উপায় আছে তবে আমি এখনই পেয়েছি:

green_horizontal_gradient.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <corners
        android:radius="3dp"
        />
    <gradient
        android:angle="0"
        android:startColor="#FF63a34a"
        android:endColor="#FF477b36"
        android:type="linear"
        />    
</shape>

half_overlay.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <solid
        android:color="#40000000"
        />
</shape>

layer_list.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <item
        android:drawable="@drawable/green_horizontal_gradient"
        android:id="@+id/green_gradient"
        />
    <item
        android:drawable="@drawable/half_overlay"
        android:id="@+id/half_overlay"
        android:top="50dp"
        />
</layer-list>

test.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >
    <TextView
        android:id="@+id/image_test"
        android:background="@drawable/layer_list"
        android:layout_width="fill_parent"
        android:layout_height="100dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:gravity="center"
        android:text="Layer List Drawable!"
        android:textColor="@android:color/white"
        android:textStyle="bold"
        android:textSize="26sp"     
        />
</RelativeLayout>

ঠিক আছে, সুতরাং মূলত আমি অনুভূমিক সবুজ গ্রেডিয়েন্টের জন্য এক্সএমএলে একটি আকৃতি গ্রেডিয়েন্ট তৈরি করেছি, 0 ডিগ্রি কোণে সেট করে উপরের অঞ্চলের বাম সবুজ বর্ণ থেকে ডান সবুজ বর্ণের দিকে চলেছি। এর পরে, আমি অর্ধ স্বচ্ছ ধূসর দিয়ে একটি আকারের আয়তক্ষেত্র তৈরি করেছি। আমি নিশ্চিত যে অতিরিক্ত স্তরটি XML- এ স্তর-তালিকাতে অন্তর্ভুক্ত করা যেতে পারে তবে আমি কীভাবে তা নিশ্চিত নই। তবে ঠিক আছে, তাহলে লেয়ারলিস্ট এক্সএমএল ফাইলটিতে ধরণের হ্যাকি অংশ আসে। আমি নীচের স্তর হিসাবে সবুজ গ্রেডিয়েন্টটি রেখেছি, তারপর দ্বিতীয় স্তর হিসাবে অর্ধ ওভারলে রাখি, উপরে থেকে 50 ডিপি দ্বারা অফসেট। স্পষ্টতই আপনি চাইবেন যে এই সংখ্যাটি সর্বদা আপনার দর্শন মাপের পরিমাণের চেয়ে অর্ধেক হওয়া উচিত, যদিও কোনও স্থির 50dp নয়। যদিও আপনি শতাংশ ব্যবহার করতে পারবেন বলে আমি মনে করি না। সেখান থেকে, আমি আমার পটভূমি হিসাবে লেয়ার_লিস্ট.এক্সএমএল ফাইলটি ব্যবহার করে আমার টেস্ট.এক্সএমএল লেআউটে একটি পাঠ্যদর্শন প্রবেশ করিয়েছি।

বিকল্প পাঠ

Tada!

আরও একটি সম্পাদনা : আমি বুঝতে পেরেছি আপনি আইটেম হিসাবে অঙ্কনযোগ্য স্তর তালিকায় কেবল আকারগুলি এম্বেড করতে পারেন যার অর্থ আপনার আর 3 টি পৃথক এক্সএমএল ফাইলের দরকার নেই! আপনি তাদের মত এইভাবে একত্রিত একই ফলাফল অর্জন করতে পারেন:

layer_list.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <item>
        <shape
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle"
            >
            <corners
                android:radius="3dp"
                />
            <gradient
                android:angle="0"
                android:startColor="#FF63a34a"
                android:endColor="#FF477b36"
                android:type="linear"
                />    
        </shape>
    </item>
    <item
        android:top="50dp" 
        >
        <shape
            android:shape="rectangle"
            >
            <solid
                android:color="#40000000"
                />
        </shape>            
    </item>
</layer-list>

আপনি নিজের পছন্দমতো আইটেম স্তর করতে পারেন! আমি প্রায় খেলার চেষ্টা করতে পারি এবং জাভা দিয়ে আরও বহুমুখী ফলাফল পেতে পারি কিনা তা দেখতে পাচ্ছি।

আমি মনে করি এটিই শেষ সম্পাদনা ... : ঠিক আছে, তাই আপনি নীচের মত জাভা মাধ্যমে অবস্থান ঠিক করতে পারেন:

    TextView tv = (TextView)findViewById(R.id.image_test);
    LayerDrawable ld = (LayerDrawable)tv.getBackground();
    int topInset = tv.getHeight() / 2 ; //does not work!
    ld.setLayerInset(1, 0, topInset, 0, 0);
    tv.setBackgroundDrawable(ld);

যাহোক! এটি আরও একটি বিরক্তিকর সমস্যার দিকে নিয়ে যায় যার ফলে আপনি টেক্সটভিউটি অঙ্কন না করা পর্যন্ত পরিমাপ করতে পারবেন না। আপনি কীভাবে এটি সম্পাদন করতে পারবেন তা আমি এখনও নিশ্চিত নই ... তবে টপআইনেসেটের জন্য ম্যানুয়ালি একটি নম্বর .োকানো কাজ করে।

আমি মিথ্যা বললাম, আরও একটি সম্পাদনা

ঠিক আছে, ধারকটির উচ্চতার সাথে মেলে এই স্তরটি কীভাবে ম্যানুয়ালি আপডেট করতে হবে তা খুঁজে পেয়েছি, সম্পূর্ণ বিবরণ এখানে পাওয়া যাবে । এই কোডটি আপনার অনক্রিট () পদ্ধতিতে যাওয়া উচিত:

final TextView tv = (TextView)findViewById(R.id.image_test);
        ViewTreeObserver vto = tv.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                LayerDrawable ld = (LayerDrawable)tv.getBackground();
                ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0);
            }
        });

আর আমি শেষ! রক্ষে! :)


এটির সাথে সমস্যাটি গ্রেডিয়েন্টটি উল্লম্ব। আমার আকৃতিটি উল্লম্বভাবে পৃথক করা প্রয়োজন (যেমন: একটি অনুভূমিক রেখা), তবে অনুভূমিক হওয়ার জন্য আমার গ্রেডিয়েন্টটি প্রয়োজন (যেমন: বাম থেকে ডানে সরানো)। এই উদাহরণ সহ, বিভাজক এবং গ্রেডিয়েন্ট উভয় উল্লম্ব হয়।
অ্যান্ড্রু

ওহ ঠিক আছে, আপনি এখন যা বলছেন তা পেয়েছি। (চিত্রগুলিতে কর্মক্ষেত্র অবরুদ্ধ, সুতরাং আমি কেবলমাত্র আমার ফোন থেকে আপনার দেখতে পেতাম, বিশদটি ভালভাবে বলতে শক্ত)। দুর্ভাগ্যক্রমে আমার কাছে এই অফহ্যান্ডের কোনও সমাধান নেই, যদিও আমি ধরে নেব যে আপনি দুটি আয়তক্ষেত্রের সাথে একটি আঁকুন আকৃতি তৈরি করতে পারেন, একটি অনুভূমিক গ্রেডিয়েন্ট সহ একটি, একটি সাদা থেকে কালো উল্লম্ব গ্রেডিয়েন্টের সাথে অর্ধেক ধাপে অর্ধেক আকারে, নীচে সারিবদ্ধ যতদূর কীভাবে করা যায় আমার এই মুহুর্তে কোনও নির্দিষ্ট উদাহরণ নেই।
কেভিন কপোকক

হ্যাঁ, আমি যা করতে পেরেছিলাম তা প্রত্যাশা করছিলাম তবে আমি এখনও এটি আবিষ্কার করতে পারি নি। আমি আপনার সাহায্যের প্রশংসা করি
এন্ড্রু

আপনাকে স্বাগতম! আমি এটি আরও একবার চেষ্টা করে দেখেছি এবং আমি মনে করি আপনি যা খুঁজছেন তা আমি পেয়েছি। আপনার জাভা (মন্তব্য অনুসারে) এর মাধ্যমে এগুলি গতিশীল করতে হতে পারে তবে এটি এখনই স্থির আকারের কৌশল করে।
কেভিন কপোকক

17
এটি কমপক্ষে +10 আপনি দিতে চান এমন ধরনের উত্তর। আমি আপনার উত্তরে লড়াইয়ের অনুভূতিটি পছন্দ করি: আপনি বনাম অ্যান্ড্রয়েড এপিআই, কে জিতবে? আমরা কি কখনো জানবো? ;) প্লাস, আপনি যে সমস্ত তুচ্ছ তত্ত্বাবধানের মুখোমুখি হয়েছিলেন তা ধরে রাখার জন্য এটি দুর্দান্ত দরকারী শিক্ষামূলক উপাদান।
andr

28

আপনি একটি স্তর-তালিকা ব্যবহার করে এক্সএমএলে গ্রেডিয়েন্ট আকারগুলি স্তর করতে পারেন। নীচের মতো ডিফল্ট অবস্থায় একটি বোতাম কল্পনা করুন, যেখানে দ্বিতীয় আইটেমটি অর্ধ-স্বচ্ছ। এটি এক ধরণের ভিগনেটিং যুক্ত করে। (দয়া করে কাস্টম-সংজ্ঞায়িত রঙগুলি ক্ষমা করুন))

<!-- Normal state. -->
<item>
    <layer-list>
        <item>  
            <shape>
                <gradient 
                    android:startColor="@color/grey_light"
                    android:endColor="@color/grey_dark"
                    android:type="linear"
                    android:angle="270"
                    android:centerColor="@color/grey_mediumtodark" />
                <stroke
                    android:width="1dp"
                    android:color="@color/grey_dark" />
                <corners
                    android:radius="5dp" />
            </shape>
        </item>
        <item>  
            <shape>
                <gradient 
                    android:startColor="#00666666"
                    android:endColor="#77666666"
                    android:type="radial"
                    android:gradientRadius="200"
                    android:centerColor="#00666666"
                    android:centerX="0.5"
                    android:centerY="0" />
                <stroke
                    android:width="1dp"
                    android:color="@color/grey_dark" />
                <corners
                    android:radius="5dp" />
            </shape>
        </item>
    </layer-list>
</item>


4

আপনি এটি কেবলমাত্র এক্সএমএল আকার ব্যবহার করে করতে পারেন - কেবল স্তর-তালিকা এবং নেতিবাচক প্যাডিং ব্যবহার করুন:

    <layer-list>

        <item>
            <shape>
                <solid android:color="#ffffff" />

                <padding android:top="20dp" />
            </shape>
        </item>

        <item>
            <shape>
                <gradient android:endColor="#ffffff" android:startColor="#efefef" android:type="linear" android:angle="90" />

                <padding android:top="-20dp" />
            </shape>
        </item>

    </layer-list>

1

এই পদ্ধতিটি ব্যবহার করে দেখুন আপনি যা চান তা করতে পারেন।
এটি স্ট্যাকের মতো তাই সাবধান থাকুন কোন আইটেমটি প্রথম বা শেষ আসে।

<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="50dp" android:start="10dp" android:left="10dp">
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:radius="3dp" />
        <solid android:color="#012d08"/>
    </shape>
</item>
<item android:top="50dp">
    <shape android:shape="rectangle">
        <solid android:color="#7c4b4b" />
    </shape>
</item>
<item android:top="90dp" android:end="60dp">
    <shape android:shape="rectangle">
        <solid android:color="#e2cc2626" />
    </shape>
</item>
<item android:start="50dp" android:bottom="20dp" android:top="120dp">
    <shape android:shape="rectangle">
        <solid android:color="#360e0e" />
    </shape>
</item>


0

আপনি কি সবুজ গ্রেডিয়েন্টের জন্য অস্বচ্ছ অস্বচ্ছতার সাথে অন্য চিত্রের শীর্ষে হাইলাইটের জন্য একটি স্বচ্ছ রঙকে প্রায় স্বচ্ছ অস্বচ্ছতার সাথে ওভারলে করার চেষ্টা করেছেন?


না আমার নেই, যদিও আমি নিশ্চিত না যে কীভাবে একটি আকারের উপর অন্যটির উপর একটি গ্রেডিয়েন্ট রাখা যায়। আমি অ্যান্ড্রয়েড ব্যবহার করে লিনিয়ারলআউটের ব্যাকগ্রাউন্ড হিসাবে আকারটি ব্যবহার করছি: ব্যাকগ্রাউন্ড = "@ ড্রয়েবল / মাইস্পাই"
অ্যান্ড্রু

একে অপরের উপরে পৃথক পৃথক ধরণের অপারেশন দিয়ে দুটি আকার স্থাপন করা কি সম্ভব? (আমি জানি না))
গ্রেগ ডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.