অ্যাপকোম্প্যাট সরঞ্জামদণ্ডে মেনু আইটেম টিটিং


95

আমি যখন AppCompatআমার Toolbarমেনু আইটেমগুলির জন্য লাইব্রেরি থেকে অঙ্কনযোগ্যগুলি ব্যবহার করি তখন আশেপাশে রঙিন কাজ করে। এটার মত:

<item
    android:id="@+id/action_clear"
    android:icon="@drawable/abc_ic_clear_mtrl_alpha"  <-- from AppCompat
    android:title="@string/clear" />

তবে আমি যদি আমার নিজস্ব আঁকাগুলি ব্যবহার করি বা AppCompatলাইব্রেরি থেকে অঙ্কনযোগ্যগুলিকে আমার নিজের প্রকল্পে অনুলিপি করি তবে এটি মোটেও আঁকবে না।

<item
    android:id="@+id/action_clear"
    android:icon="@drawable/abc_ic_clear_mtrl_alpha_copy"  <-- copy from AppCompat
    android:title="@string/clear" />

AppCompat Toolbarসেই লাইব্রেরি থেকে কেবল রঙিন আঁকতে কিছু বিশেষ জাদু রয়েছে কি ? আমার নিজস্ব অঙ্কনযোগ্যকে নিয়ে কাজ করার কোনও উপায়?

এপিআই লেভেল 19 ডিভাইসে এটি চালানো compileSdkVersion = 21এবং এর targetSdkVersion = 21থেকে সমস্ত কিছু ব্যবহার করেAppCompat

abc_ic_clear_mtrl_alpha_copyabc_ic_clear_mtrl_alphapng এর হুবহু কপিAppCompat

সম্পাদনা করুন:

টিন্টিংটি আমার থিমটিতে আমি যে মান নির্ধারণ করেছি তার উপর ভিত্তি করে android:textColorPrimary

যেমন <item name="android:textColorPrimary">#00FF00</item>আমাকে সবুজ রঙের রঙ দেয়।

স্ক্রিনশট

অ্যাপকম্প্যাট থেকে অঙ্কনযোগ্য হিসাবে প্রত্যাশার সাথে কাজ করে টিংটিং অ্যাপকম্প্যাট থেকে অঙ্কনযোগ্য হিসাবে প্রত্যাশার সাথে কাজ করে টিংটিং

অ্যাপকম্প্যাট থেকে অনুলিপিযুক্ত অনুলিপি সহ কাজ না করা টিটিং অ্যাপকম্প্যাট থেকে অনুলিপিযুক্ত অনুলিপি সহ কাজ না করা টিটিং


উভয় শৈলীর একই পিতা বা মাতা আছে? আপনি যদি নিজের সাথে শীর্ষ শৈলী প্রসারিত করেন?
জি_ভি

শৈলীতে কোনও পার্থক্য নেই। পার্থক্যটি হ'ল অঙ্কনযোগ্য, যা উভয় .png ফাইল
গ্রেভ

অঙ্কনযোগ্যটি কোডটিতে অঙ্কনযোগ্য মূল অ্যাপকোম্ব্যাটটির একটি সঠিক অনুলিপিটির মতো দেখাচ্ছে?
জি_ভি

এগুলি পিএনজি ফাইল, যা আমি অনুলিপি করেছি। তারা ঠিক একই আছে।
গ্রেভ

সুতরাং যদি আপনার কোডটি একই শৈলী এবং একই চিত্র থাকে তবে মূল থেকে আলাদা কোথায়?
জি_ভি

উত্তর:


31

কারণ আপনি যদি অ্যাপকোম্পেটের টিন্ট ম্যানেজারের উত্স কোডটি একবার দেখে থাকেন তবে আপনি দেখতে পাবেন:

/**
 * Drawables which should be tinted with the value of {@code R.attr.colorControlNormal},
 * using the default mode.
 */
private static final int[] TINT_COLOR_CONTROL_NORMAL = {
        R.drawable.abc_ic_ab_back_mtrl_am_alpha,
        R.drawable.abc_ic_go_search_api_mtrl_alpha,
        R.drawable.abc_ic_search_api_mtrl_alpha,
        R.drawable.abc_ic_commit_search_api_mtrl_alpha,
        R.drawable.abc_ic_clear_mtrl_alpha,
        R.drawable.abc_ic_menu_share_mtrl_alpha,
        R.drawable.abc_ic_menu_copy_mtrl_am_alpha,
        R.drawable.abc_ic_menu_cut_mtrl_alpha,
        R.drawable.abc_ic_menu_selectall_mtrl_alpha,
        R.drawable.abc_ic_menu_paste_mtrl_am_alpha,
        R.drawable.abc_ic_menu_moreoverflow_mtrl_alpha,
        R.drawable.abc_ic_voice_search_api_mtrl_alpha,
        R.drawable.abc_textfield_search_default_mtrl_alpha,
        R.drawable.abc_textfield_default_mtrl_alpha
};

/**
 * Drawables which should be tinted with the value of {@code R.attr.colorControlActivated},
 * using the default mode.
 */
private static final int[] TINT_COLOR_CONTROL_ACTIVATED = {
        R.drawable.abc_textfield_activated_mtrl_alpha,
        R.drawable.abc_textfield_search_activated_mtrl_alpha,
        R.drawable.abc_cab_background_top_mtrl_alpha
};

/**
 * Drawables which should be tinted with the value of {@code android.R.attr.colorBackground},
 * using the {@link android.graphics.PorterDuff.Mode#MULTIPLY} mode.
 */
private static final int[] TINT_COLOR_BACKGROUND_MULTIPLY = {
        R.drawable.abc_popup_background_mtrl_mult,
        R.drawable.abc_cab_background_internal_bg,
        R.drawable.abc_menu_hardkey_panel_mtrl_mult
};

/**
 * Drawables which should be tinted using a state list containing values of
 * {@code R.attr.colorControlNormal} and {@code R.attr.colorControlActivated}
 */
private static final int[] TINT_COLOR_CONTROL_STATE_LIST = {
        R.drawable.abc_edit_text_material,
        R.drawable.abc_tab_indicator_material,
        R.drawable.abc_textfield_search_material,
        R.drawable.abc_spinner_mtrl_am_alpha,
        R.drawable.abc_btn_check_material,
        R.drawable.abc_btn_radio_material
};

/**
 * Drawables which contain other drawables which should be tinted. The child drawable IDs
 * should be defined in one of the arrays above.
 */
private static final int[] CONTAINERS_WITH_TINT_CHILDREN = {
        R.drawable.abc_cab_background_top_material
};

যার বেশিরভাগ অর্থ হ'ল তাদের নির্দিষ্ট সংস্থান রয়েছে যা রঙিন হতে শ্বেত তালিকাভুক্ত।

তবে আমি অনুমান করি আপনি সর্বদা দেখতে পাবেন যে তারা কীভাবে এই চিত্রগুলিকে আঁকছেন এবং একইরকম করছেন। এটি একটি অঙ্কনযোগ্য রঙিন ফিল্টার সেট হিসাবে সহজ।


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

8
আমি জানি এটি একটি স্পর্শকাতর প্রশ্ন তবে কেন একটি সাদা তালিকা রয়েছে? এটি যদি এই আইকনগুলির সাহায্যে রঙিন করতে পারে তবে আমরা কেন আমাদের নিজস্ব আইকনগুলি রঙ করতে পারি না? এছাড়াও, যখন আপনি সর্বাধিক গুরুত্বপূর্ণ বিষয়টি ছেড়ে যান: অ্যাকশন বার আইকনগুলি (কাস্টম রঙের সাথে) রাখার সময় প্রায় সমস্ত কিছু পশ্চাদপটে সামঞ্জস্যপূর্ণ (অ্যাপকম্প্যাট সহ) তৈরি করার মূল বিষয়টি।
জসোল্ট সাফরানি

4
গুগলের ইস্যু ট্র্যাকারে এটির জন্য একটি সমস্যা রয়েছে যা স্থির হিসাবে চিহ্নিত হয়েছে, তবে এটি আমার পক্ষে কাজ করে না তবে আপনি এটি ট্র্যাক করতে পারেন: ইস্যুজেট্র্যাকার.ইল.ইউএসআই
নিকনেটনিকো

তাদের দাবি এটি স্থির, তবে তা হয়নি। হ্যাঁ, আমি অ্যান্ড্রয়েড থিম ইঞ্জিন, অ্যাপকম্প্যাট এবং এর সাথে সম্পর্কিত সমস্ত ক্রেপকে ঘৃণা করি। এটি কেবলমাত্র "গিথুব রেপো ব্রাউজার" নমুনা অ্যাপ্লিকেশানের জন্য কাজ করে।
মার্টিন মার্কনকিনি

98

নতুন সমর্থন লাইব্রেরি v22.1 এর পরে, আপনি এর অনুরূপ কিছু ব্যবহার করতে পারেন:

  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_home, menu);
        Drawable drawable = menu.findItem(R.id.action_clear).getIcon();

        drawable = DrawableCompat.wrap(drawable);
        DrawableCompat.setTint(drawable, ContextCompat.getColor(this,R.color.textColorPrimary));
        menu.findItem(R.id.action_clear).setIcon(drawable);
        return true;
    }

4
আমি বলব যে এক্ষেত্রে পুরাতনটি setColorFilter()বেশ পছন্দনীয়।
নটারিও

@ এমওয়াই, সেটকলার ফিল্টার () আরও বেশি পছন্দযোগ্য কেন?
বন্যদেব

4
@ উইলদেব ব্রিভিটি আপনি যখন মেনু.ফাইন্ড আইটেম ()। GetIcon ()। সেটকলার ফিল্টার () যেতে পারেন তখন সমর্থন ড্রয়যোগ্য কমপ্যাট ক্লাসটিকে কেন বিরক্ত করবেন? একটি লাইনার এবং পরিষ্কার।
নটারিও

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

রঙিন হওয়ার জন্য বিভিন্ন লজিকের প্রয়োজন নেই এবং ভবিষ্যতে কোনও পরিবর্তন করার প্রয়োজন নেই।
জেমশিত ইস্কেন্দ্রভ

84

একটিতে একটি ColorFilter(টিন্ট) সেট MenuItemকরা সহজ। এখানে একটি উদাহরণ:

Drawable drawable = menuItem.getIcon();
if (drawable != null) {
    // If we don't mutate the drawable, then all drawable's with this id will have a color
    // filter applied to it.
    drawable.mutate();
    drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
    drawable.setAlpha(alpha);
}

উপরের কোডটি খুব সহায়ক যদি আপনি বিভিন্ন থিম সমর্থন করতে চান এবং কেবল রঙ বা স্বচ্ছতার জন্য আপনার অতিরিক্ত অনুলিপি পেতে চান না।

ColorFilterওভারফ্লো আইকন সহ মেনুতে সমস্ত অঙ্কনযোগ্যগুলিতেএকটি সেট করতে সহায়তা সহায়ক শ্রেণীর জন্য এখানে ক্লিক করুন

ইন onCreateOptionsMenu(Menu menu)শুধু কল MenuColorizer.colorMenu(this, menu, color);আপনার মেনু এবং voila বৃদ্ধি পরে; আপনার আইকন রঙিন হয়


4
আমি আমার ডেস্কের বিরুদ্ধে মাথা ঘুরিয়ে দিয়েছি কেন আমার আইকনগুলির সমস্ত রঙিন হচ্ছে তা বের করার চেষ্টা করছিলাম, অঙ্কনযোগ্য.মুটেট () সম্পর্কে মাথা রেখেই ধন্যবাদ!
স্কট কুপার

52

app:iconTintSupportMenuInflaterসমর্থন লাইব্রেরি থেকে অ্যাট্রিবিউট প্রয়োগ করা হয় (কমপক্ষে 28.0.0 এ)।

15 এবং ততোধিক এপিআই সহ সফলভাবে পরীক্ষিত।

মেনু রিসোর্স ফাইল:

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menu_settings"
        android:icon="@drawable/ic_settings_white_24dp"
        app:iconTint="?attr/appIconColorEnabled"        <!-- using app name space instead of android -->
        android:menuCategory="system"
        android:orderInCategory="1"
        android:title="@string/menu_settings"
        app:showAsAction="never"
        />

    <item
        android:id="@+id/menu_themes"
        android:icon="@drawable/ic_palette_white_24dp"
        app:iconTint="?attr/appIconColorEnabled"
        android:menuCategory="system"
        android:orderInCategory="2"
        android:title="@string/menu_themes"
        app:showAsAction="never"
        />

    <item
        android:id="@+id/action_help"
        android:icon="@drawable/ic_help_white_24dp"
        app:iconTint="?attr/appIconColorEnabled"
        android:menuCategory="system"
        android:orderInCategory="3"
        android:title="@string/menu_help"
        app:showAsAction="never"
        />

</menu>

(এই ক্ষেত্রে ?attr/appIconColorEnabledঅ্যাপের থিমগুলিতে একটি কাস্টম রঙ বৈশিষ্ট্য ছিল এবং আইকন সংস্থানগুলি ভেক্টর ড্রয়যোগ্য ছিল ables


4
এটি নতুন গৃহীত উত্তর হওয়া উচিত! এছাড়াও, দয়া করে নোট করুন android:iconTintএবং android:iconTintModeকাজ করবেন না, তবে আকর্ষণীয় (যেমন আমার নিজের ভেক্টর ড্রয়াবল, এপিআই> = 21) এর মতো কাজের app:পরিবর্তে android:পূর্বনির্ধারণ করুন
সেবাস্তিয়ান আলভারেজ রদ্রিগেজ

যদি প্রোগ্রামিয়ালি কল করা হয়: নোট করুন যে SupportMenuInflaterমেনুটি SupportMenuপছন্দ না হলে কোনও কাস্টম যুক্তি প্রয়োগ করবে না MenuBuilderএটি কেবল নিয়মিত হয়ে পড়ে MenuInflater
geekley

এই ক্ষেত্রে, ব্যবহার AppCompatActivity.startSupportActionMode(callback)এবং যথাযথ সমর্থন বাস্তবায়নগুলি androidx.appcompatকলব্যাকের মধ্যে পাঠানো হবে।
geekley

কেবল দুর্দান্ত ... উত্তরের জন্য ধন্যবাদ ..
কলপেশ কুন্ডানানী

30

আমি ব্যক্তিগতভাবে এই লিঙ্কটি থেকে এই পদ্ধতির পছন্দ করেছি

নিম্নলিখিতগুলির সাথে একটি এক্সএমএল লেআউট তৈরি করুন:

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_action_something"
    android:tint="@color/color_action_icons_tint"/>

এবং আপনার মেনু থেকে এই অঙ্কনযোগ্য রেফারেন্স:

<item
    android:id="@+id/option_menu_item_something"
    android:icon="@drawable/ic_action_something_tined"

4
যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত পৃষ্ঠাগুলি পরিবর্তিত হলে লিঙ্ক-শুধুমাত্র উত্তরগুলি অবৈধ হতে পারে।
টমলপ্রড

আমি মন্তব্য সম্পাদনা করেছি আপনার মন্তব্যের জন্য আপনাকে ধন্যবাদ। @ টমলপ্রড
এন জে

4
এটি আমার পছন্দসই সমাধান। যাইহোক, এটি লক্ষণীয় গুরুত্বপূর্ণ যে আপনি যখন নতুন ভেক্টর অঙ্কনযোগ্য প্রকারগুলি উত্স হিসাবে ব্যবহার করছেন তখন এই সমাধানটি কার্যকর হবে না work
মাইকেল ডি সোটো

4
@ হাইগম্ম এই সমাধানটির জন্য এপিআই> = 21 প্রয়োজন Also এছাড়াও এটি ভেক্টরগুলির পক্ষেও কাজ করে।
নিউরোট্রান্সমিটার

4
এবং এটি ভেক্টরগুলির সাথে কাজ করা উচিত নয়, মূল ট্যাগটি bitmap। ভেক্টরগুলিকে রঙ করার অন্যান্য উপায় রয়েছে। সম্ভবত কেউ এখানে ভেক্টর রঙ যুক্ত করতে পারে ...
মিলোসমনস

11

এই থ্রেডের বেশিরভাগ সমাধানগুলি হয় একটি নতুন এপিআই ব্যবহার করে, বা প্রতিবিম্ব ব্যবহার করে, বা স্ফীতিতে পৌঁছানোর জন্য নিবিড় দৃষ্টিকোণ ব্যবহার করে MenuItem

তবে এটি করার জন্য আরও মার্জিত পদ্ধতি রয়েছে। আপনার একটি কাস্টম টুলবার প্রয়োজন, কারণ আপনার "প্রয়োগ কাস্টম টিন্ট" ব্যবহারের ক্ষেত্রে পাবলিক স্টাইলিং / থিমিং এপিআইয়ের সাথে ভাল খেলা হয় না।

public class MyToolbar extends Toolbar {
    ... some constructors, extracting mAccentColor from AttrSet, etc

    @Override
    public void inflateMenu(@MenuRes int resId) {
        super.inflateMenu(resId);
        Menu menu = getMenu();
        for (int i = 0; i < menu.size(); i++) {
            MenuItem item = menu.getItem(i);
            Drawable icon = item.getIcon();
            if (icon != null) {
                item.setIcon(applyTint(icon));
            }
        }
    }
    void applyTint(Drawable icon){
        icon.setColorFilter(
           new PorterDuffColorFilter(mAccentColor, PorterDuff.Mode.SRC_IN)
        );
    }

}

আপনার কার্যকলাপ / ফ্রেগমেন্ট কোডটিতে আপনি কল করেছেন তা নিশ্চিত করুন:

toolbar.inflateMenu(R.menu.some_menu);
toolbar.setOnMenuItemClickListener(someListener);

কোন প্রতিবিম্ব নেই, দেখার কোন দৃশ্য নেই, এবং এত কোড নয়, হাহ?

এবং এখন আপনি হাস্যকর উপেক্ষা করতে পারেন onCreateOptionsMenu/onOptionsItemSelected


প্রযুক্তিগতভাবে, আপনি একটি দর্শন লক করছেন। আপনি দৃশ্যের পুনরাবৃত্তি করছেন এবং নিশ্চিত করছেন যে এগুলি নাল নয়। ;)
মার্টিন মার্কনকিনি

আপনি অবশ্যই একটি উপায়ে সঠিকভাবে Menu#getItem()রয়েছেন :-) তবে, টুলবারে জটিলতা হ'ল (1), কারণ আইটেমি অ্যারেলিস্টে সঞ্চিত রয়েছে। যা View#findViewByIdট্র্যাভারসাল থেকে পৃথক (যা আমি আমার জবাব দেখার জন্য উল্লেখ করেছি), এর জটিলতা স্থির হওয়া থেকে অনেক দূরে :-)
ড্রউ

সম্মত, আসলে, আমি খুব অনুরূপ একটি জিনিস করেছি। আমি এখনও হতবাক হয়েছি যে এন্ড্রয়েড এত বছর পরেও এই সবগুলি প্রবাহিত করে নি…
মার্টিন মার্কনকিনি

এই পদ্ধতির সাহায্যে আমি কীভাবে ওভারফ্লো আইকন এবং হ্যামবার্গার আইকনটির রঙ পরিবর্তন করতে পারি?
সান্দ্রা

8

আমি যে সমাধানটি ব্যবহার করি তা এখানে; আপনি প্রিপার্পেপশনমেনু () বা সমতুল্য স্থানের পরে এটি কল করতে পারেন। পরিবর্তনের () কারণ হ'ল যদি আপনি একাধিক স্থানে আইকনগুলি ব্যবহার করেন; মিউটেট ব্যতীত, তারা সকলেই একই রঙিন হবে।

public class MenuTintUtils {
    public static void tintAllIcons(Menu menu, final int color) {
        for (int i = 0; i < menu.size(); ++i) {
            final MenuItem item = menu.getItem(i);
            tintMenuItemIcon(color, item);
            tintShareIconIfPresent(color, item);
        }
    }

    private static void tintMenuItemIcon(int color, MenuItem item) {
        final Drawable drawable = item.getIcon();
        if (drawable != null) {
            final Drawable wrapped = DrawableCompat.wrap(drawable);
            drawable.mutate();
            DrawableCompat.setTint(wrapped, color);
            item.setIcon(drawable);
        }
    }

    private static void tintShareIconIfPresent(int color, MenuItem item) {
        if (item.getActionView() != null) {
            final View actionView = item.getActionView();
            final View expandActivitiesButton = actionView.findViewById(R.id.expand_activities_button);
            if (expandActivitiesButton != null) {
                final ImageView image = (ImageView) expandActivitiesButton.findViewById(R.id.image);
                if (image != null) {
                    final Drawable drawable = image.getDrawable();
                    final Drawable wrapped = DrawableCompat.wrap(drawable);
                    drawable.mutate();
                    DrawableCompat.setTint(wrapped, color);
                    image.setImageDrawable(drawable);
                }
            }
        }
    }
}

এটি উপচে পড়ার যত্ন নেবে না, তবে তার জন্য আপনি এটি করতে পারেন:

বিন্যাস:

<android.support.v7.widget.Toolbar
    ...
    android:theme="@style/myToolbarTheme" />

শৈলী:

<style name="myToolbarTheme">
        <item name="colorControlNormal">#FF0000</item>
</style>

এটি অ্যাপকম্প্যাট v23.1.0 হিসাবে কাজ করে।


2

এটি আমার পক্ষে কাজ করেছে:

override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        val inflater = menuInflater
        inflater.inflate(R.menu.player_menu, menu)

        //tinting menu item:
        val typedArray = theme.obtainStyledAttributes(IntArray(1) { android.R.attr.textColorSecondary })
        val textColor = typedArray.getColor(0, 0)
        typedArray.recycle()

        val item = menu?.findItem(R.id.action_chapters)
        val icon = item?.icon

        icon?.setColorFilter(textColor, PorterDuff.Mode.SRC_IN);
        item?.icon = icon
        return true
    }

অথবা আপনি অঙ্কনযোগ্য এক্সএমএলতে রঙিন ব্যবহার করতে পারেন:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:tint="?android:textColorSecondary"
    android:viewportWidth="384"
    android:viewportHeight="384">
    <path
        android:fillColor="#FF000000"

        android:pathData="M0,277.333h384v42.667h-384z" />
    <path
        android:fillColor="#FF000000"
        android:pathData="M0,170.667h384v42.667h-384z" />
    <path
        android:fillColor="#FF000000"
        android:pathData="M0,64h384v42.667h-384z" />
</vector>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.