কীভাবে কাস্টম বোতামের রাজ্য যুক্ত করবেন


132

উদাহরণস্বরূপ, ডিফল্ট বোতামটির রাজ্য এবং পটভূমির চিত্রগুলির মধ্যে নিম্নলিখিত নির্ভরতা রয়েছে:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="false" android:state_enabled="true"
        android:drawable="@drawable/btn_default_normal" />
    <item android:state_window_focused="false" android:state_enabled="false"
        android:drawable="@drawable/btn_default_normal_disable" />
    <item android:state_pressed="true" 
        android:drawable="@drawable/btn_default_pressed" />
    <item android:state_focused="true" android:state_enabled="true"
        android:drawable="@drawable/btn_default_selected" />
    <item android:state_enabled="true"
        android:drawable="@drawable/btn_default_normal" />
    <item android:state_focused="true"
        android:drawable="@drawable/btn_default_normal_disable_focused" />
    <item
        android:drawable="@drawable/btn_default_normal_disable" />
</selector>

আমি কীভাবে আমার নিজস্ব কাস্টম অবস্থা (স্মেথ লাইক android:state_custom) সংজ্ঞায়িত করতে পারি , তারপরে আমি এটিকে আমার বোতামের চাক্ষুষ চেহারাটি পরিবর্তনশীলভাবে ব্যবহার করতে পারি?


আমি যখন দুটি পাসওয়ার্ড বাক্সে একটু চেকমার্ক দেখাতে মেলে তখন এডিটেক্সট ভিউয়ের জন্য অতিরিক্ত রাজ্য চাইছিলাম want
নাথান শোয়ারম্যান

উত্তর:


275

@ (টেড হপ্প) দ্বারা নির্দেশিত সমাধানটি কাজ করে তবে কিছুটা সংশোধন দরকার: নির্বাচক হিসাবে আইটেমটির একটি "অ্যাপ:" উপসর্গের প্রয়োজন হয়, অন্যথায় স্ফীতকারী নাম স্থানটি সঠিকভাবে চিনতে পারে না, এবং নিঃশব্দে ব্যর্থ হবে; অন্তত আমার ক্ষেত্রে এটি ঘটে।

আমাকে আরও কিছু বিশদ সহ পুরো সমাধানটি এখানে প্রতিবেদন করার অনুমতি দিন:

প্রথমে "res / মান / attrs.xML" ফাইলটি তৈরি করুন:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="food">
        <attr name="state_fried" format="boolean" />
        <attr name="state_baked" format="boolean" />
    </declare-styleable>
</resources>

তারপরে আপনার কাস্টম ক্লাসটি সংজ্ঞায়িত করুন। উদাহরণস্বরূপ, এটি ক্লাস "বোতাম" থেকে প্রাপ্ত "ফুডবটন" শ্রেণি হতে পারে। আপনাকে কোনও কনস্ট্রাক্টর প্রয়োগ করতে হবে; এটি কার্যকর করুন যা মনে হয় এটি স্ফীতকারী দ্বারা ব্যবহৃত:

public FoodButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}

উত্পন্ন শ্রেণীর শীর্ষে:

private static final int[] STATE_FRIED = {R.attr.state_fried};
private static final int[] STATE_BAKED = {R.attr.state_baked};

এছাড়াও, আপনার রাষ্ট্র পরিবর্তনশীল:

private boolean mIsFried = false;
private boolean mIsBaked = false;

এবং সেটটার একটি দম্পতি:

public void setFried(boolean isFried) {mIsFried = isFried;}
public void setBaked(boolean isBaked) {mIsBaked = isBaked;}

তারপরে "onCreateDrawableState" ফাংশনটি ওভাররাইড করুন:

@Override
protected int[] onCreateDrawableState(int extraSpace) {
    final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
    if (mIsFried) {
        mergeDrawableStates(drawableState, STATE_FRIED);
    }
    if (mIsBaked) {
        mergeDrawableStates(drawableState, STATE_BAKED);
    }
    return drawableState;
}

অবশেষে, এই ধাঁধার সবচেয়ে সূক্ষ্ম টুকরা; নির্বাচক স্টেটলিস্টড্রেবলের সংজ্ঞা দিচ্ছেন যা আপনি আপনার উইজেটের পটভূমি হিসাবে ব্যবহার করবেন। এটি ফাইল "রেজো / ড্রইয়েবল / ফুড_বুটন.এক্সএমএল":

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.mydomain.mypackage">
<item
    app:state_baked="true"
    app:state_fried="false"
    android:drawable="@drawable/item_baked" />
<item
    app:state_baked="false"
    app:state_fried="true"
    android:drawable="@drawable/item_fried" />
<item
    app:state_baked="true"
    app:state_fried="true"
    android:drawable="@drawable/item_overcooked" />
<item
    app:state_baked="false"
    app:state_fried="false"
    android:drawable="@drawable/item_raw" />
</selector>

"অ্যাপ:" উপসর্গটি লক্ষ্য করুন, যেখানে স্ট্যান্ডার্ড অ্যান্ড্রয়েড রাজ্যের সাথে আপনি "অ্যান্ড্রয়েড:" উপসর্গটি ব্যবহার করতেন। এক্সএমএল নেমস্পেসটি ইনফ্লেটারের দ্বারা সঠিক ব্যাখ্যার জন্য অত্যন্ত গুরুত্বপূর্ণ এবং আপনি যে ধরণের প্রকল্পে বৈশিষ্ট্য যুক্ত করছেন তার উপর নির্ভর করে। যদি এটি কোনও অ্যাপ্লিকেশন হয় তবে আপনার অ্যাপ্লিকেশনটির প্রকৃত প্যাকেজের নামের সাথে com.mydomain.mypackage প্রতিস্থাপন করুন (আবেদনের নাম বাদ দেওয়া হয়েছে)। যদি এটি একটি লাইব্রেরি হয় তবে আপনাকে অবশ্যই "http://schemas.android.com/apk/res-auto" ব্যবহার করতে হবে (এবং সরঞ্জাম R17 বা তার পরে ব্যবহার করা উচিত) অথবা আপনি রানটাইম ত্রুটি পাবেন।

কয়েকটি নোট:

  • মনে হচ্ছে আপনার "রিফ্রেশড্রেইবল স্টেট" ফাংশনটি কল করার দরকার নেই, আমার ক্ষেত্রে কমপক্ষে সমাধানটি যেমন কাজ করে তেমনি

  • বিন্যাসের এক্সএমএল ফাইলে আপনার কাস্টম ক্লাসটি ব্যবহার করতে, আপনাকে পুরোপুরি যোগ্যতাসম্পন্ন নামটি নির্দিষ্ট করতে হবে (যেমন com.mydomain.mypackage.FoodButton)

  • আরও জটিল রাষ্ট্রের সংমিশ্রণের প্রতিনিধিত্ব করার জন্য আপনি কাস্টম রাজ্যের সাথে উইল মিক্স-আপ স্ট্যান্ডার্ড স্টেটস (যেমন অ্যান্ড্রয়েড: চাপা, অ্যান্ড্রয়েড: সক্ষম, অ্যান্ড্রয়েড: নির্বাচিত) হিসাবে করতে পারেন


3
আপডেট: যদি কাস্টম ক্লাসটি বোতামের পরিবর্তে টেক্সটভিউ থেকে প্রাপ্ত হয়, তবে রিফ্রেশড্রেবল স্টেটে কলটি প্রয়োজনীয় বলে মনে হয়, অন্যথায় উইজেটের উপস্থিতি আপডেট হয় না। কলটি সেটারে স্থাপন করা হবে। আমি অন্য ক্লাস চেষ্টা করিনি। টেস্টগুলি একটি ফ্রয়েও ডিভাইসে সম্পাদিত হয়েছিল।
জর্জিও বারচিয়েসি

17
refreshDrawableStateস্পষ্টভাবে গুরুত্বপূর্ণ। সত্যই কখন এটি প্রয়োজন তা আমি নিশ্চিত নই। তবে আমার ক্ষেত্রে এটি রাষ্ট্রের প্রোগ্রাম হিসাবে সেট করার সময় প্রয়োজন ছিল was আমার ধারণা এটি অন টচ এভেন্টে স্বয়ংক্রিয়ভাবে ভিউ ক্লাস থেকে কল হয়েছিল। আমি সেট সেটলেটেড পদ্ধতিতে এটি আরও ভালভাবে যুক্ত করব।
বুর্গি

1
জর্জিওবারচিয়েসি, আমার দুটি কাস্টম বাটন আছে এবং আমি যখন একটি বোতামের অনক্লিক ইভেন্ট থেকে উভয় বোতামের স্থিতি পরিবর্তন করার চেষ্টা করি তখন কেবল ক্লিক করা বোতামটি পরিবর্তিত হয়ে যায়, আমি মনে করি @ বার্গি ঠিক আছে যে রিফ্রেশড্রেইবল স্টেট পদ্ধতিটি ডাকা হবে onClickEvent। আপনার দুর্দান্ত টিউটোরিয়ালটির জন্য আবার ধন্যবাদ :)
বোল্টন

2
কিন্তু আপনি কীভাবে কাস্টম রাজ্যগুলি ব্যবহার করতে পারবেন না boolean? বা নির্বাচকরা কি কেবল বুলিয়ানগুলিতেই কাজ করছেন?
পিটারডকে

2
এটা কিভাবে কাজ করে? আমি বলতে চাইছি, কীভাবে বৈশিষ্ট্যটি সত্য / মিথ্যা হিসাবে আপডেট হয়? কে এটি আপডেট করে? অঙ্কনীয় স্থানে মার্জ করা কি কেবল স্থানীয় ভেরিয়েবলটি সত্য হলে, বৈশিষ্ট্যের রাজ্য বা মান আপডেট করে? কোন কোডটি সঠিকভাবে আর.আট.আর.স্টেট_ফ্রিড আপডেট করবে?
kAmol

10

এই থ্রেডটি দেখায় যে কীভাবে বোতামগুলিতে এবং পছন্দগুলিতে কাস্টম স্টেট যুক্ত করা যায়। (আপনি যদি নিজের ব্রাউজারে নতুন গুগল গ্রুপগুলি দেখতে না পান তবে এখানে থ্রেডের একটি অনুলিপি রয়েছে ))


+1 অনেক ধন্যবাদ, টেড! এখনই সমস্যার উত্স চলে গেছে তাই আমি প্রকৃত বাস্তবায়নে উঠিনি to তবে আমার গ্রাহককে কী আবার এটিতে ফিরে আসা উচিত আমি আপনাকে যেভাবে নির্দেশ করেছি সেভাবে চেষ্টা করব।
ভিট খুডেনকো

আমার যা প্রয়োজন তা ঠিক দেখতে দেখতে, তবে আমার কাস্টম রাজ্যের জন্য রাষ্ট্রীয় তালিকা
ড্রয়াবলগুলি

আপনি কি রিফ্রেশড্রেবল স্টেট () কল করছেন?
টেড হপ

লিঙ্কগুলি মারা গেছে।
মিচ

@ মিচ - আচ্ছা, এটি খুব খারাপ। আমি কিছু প্রতিস্থাপনের লিঙ্কগুলি খুঁজে পেতে পারি কিনা তা আমি দেখতে পাব। যদি তা না হয় তবে আমি এই উত্তরটি মুছে ফেলব, কারণ এটি মূলত অকেজো। এদিকে, গৃহীত উত্তরের প্রয়োজনীয় সমস্ত তথ্য রয়েছে।
টেড হপ

6

refreshDrawableStateইউআই থ্রেডের মধ্যে কল করতে ভুলবেন না :

mHandler.post(new Runnable() {
    @Override
    public void run() {
        refreshDrawableState();
    }
});

সবকিছু ঠিকঠাক দেখা সত্ত্বেও আমার বোতামটি কেন তার রাজ্যটি পরিবর্তন করছে না তা নির্ধারণ করতে আমার অনেক সময় লেগেছে।


কোথায় বা কখন এই হ্যান্ডলারটি পোস্ট করব?
আর্থার মেলো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.