প্রোগ্রামারিকভাবে নির্বাচক চিত্রগুলি প্রতিস্থাপন করুন


116

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

এখানে নির্বাচকের একটি কোড রয়েছে:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/iconSelector">
  <!-- pressed -->
  <item android:state_pressed="true" android:drawable="@drawable/btn_icon_hl" />
  <!-- focused -->
  <item android:state_focused="true" android:drawable="@drawable/btn_icon_hl" />
  <!-- default -->
  <item android:drawable="@drawable/btn_icon" />
</selector>

আমি প্রতিস্থাপন করতে btn_icon_hlএবং btn_iconঅন্যান্য চিত্র সহ সক্ষম হতে চাই ।


দু'জন নির্বাচক রেখে তাদের বদলে নেওয়া কি সহজ হবে না?
বিগস্টোনস

2
এতে সমস্যাটি হ'ল আপনি শত শত এক্সএমএল ফাইল দিয়ে শেষ করতে পারেন।
এমিল

উত্তর:


244

আমি যতদূর সন্ধান করতে সক্ষম হয়েছি (আমি নিজের মতো করে কিছু করার চেষ্টা করেছি), স্টেটলিস্টড্রাব্যাবল ইতিমধ্যে সংজ্ঞায়িত হওয়ার পরে একটি একক রাষ্ট্রের পরিবর্তন করার উপায় নেই। আপনি তবে কোডের মাধ্যমে একটি নতুনকে সংজ্ঞায়িত করতে পারেন:

StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
    getResources().getDrawable(R.drawable.pressed));
states.addState(new int[] {android.R.attr.state_focused},
    getResources().getDrawable(R.drawable.focused));
states.addState(new int[] { },
    getResources().getDrawable(R.drawable.normal));
imageView.setImageDrawable(states);

এবং আপনি কেবল তাদের দু'টিকে হাতের কাছে রাখতে পারেন, বা আপনার প্রয়োজন অনুসারে আলাদা একটি তৈরি করতে পারেন।


1
আমি এটি কোনও চিত্র দর্শনে যুক্ত করতে পারিনি। সেটস্টেট এটিতে উপলব্ধ নেই।
ড্রপসফিউজপিটার

2
আসলে আমি এটি পেয়েছি, এর সেটআইমেজড্রেইবল () আপনাকে ধন্যবাদ অনেক ধন্যবাদ এটি কাজ করেছে এবং আমার প্রায় 40 টি এক্সএমএল ফাইল সংরক্ষণ করেছে!
ড্রপসফিউজপিটার

2
সুতরাং আমি এই সম্পর্কিত আরও একটি নোট আছে। আমি আশা করছিলাম আপনি উত্তর দিতে পারেন। আমার কাছে এই নির্বাচকটি কাস্টম নিয়ন্ত্রণের ভিতরে থাকা চিত্রভিউতে সেট করেছে। কাস্টম নিয়ন্ত্রণের একটি পটভূমি হিসাবে একজন নির্বাচকও রয়েছে। সুতরাং পুরো নিয়ন্ত্রণের নির্বাচক কাজ করে, যখন চিত্রকল্পের নির্বাচকটি কাজ করে না। আমি কি কিছু ভুল করছি? কোন অনুক্রম আছে?
ড্রপসফিউজপিটার

1
আপনাকে স্বাগতম! হ্যাঁ আমি জানি না কেন আমি সেটস্টেট লাগিয়েছিলাম, সেটামেজড্র্যাব্যাবল হওয়া উচিত, আপনি ঠিক বলেছেন। আপনার অন্যান্য প্রশ্ন অনুসারে, আমি আপনার কাস্টম নিয়ন্ত্রণ এবং এর নির্বাচকের জন্য কোডটি দিয়ে একটি নতুন প্রশ্ন পোস্ট করার পরামর্শ দিচ্ছি, আমি তার উত্তরের বিষয়ে নিশ্চিত নই।
কেভিন কপক

3
আমি একই কোড ব্যবহার করছি। সর্বদা যে চিত্রটি আমি ----> নতুন ইনট [] {} স্থিতিতে নির্দিষ্ট করে রেখেছি। আমি কোথায় ভুল ছিলাম ??
KK_07k11A0585

6

আমারও একই সমস্যা ছিল এবং এটি সমাধানের জন্য আরও একধাপ এগিয়ে গেলাম। তবে কেবলমাত্র সমস্যাটি হল আপনি xML এ NavStateListDrawable নির্দিষ্ট করতে পারবেন না, সুতরাং আপনাকে কোডের মাধ্যমে আপনার UI উপাদানটির ব্যাকগ্রাউন্ড সেট করতে হবে। তারপরে প্রত্যেকবার মূল অঙ্কনীয় স্তরটির স্তর পরিবর্তন হয় এবং আপনি শিশু স্তরের তালিকার স্তরটিও আপডেট করেন তা নিশ্চিত করার জন্য onStateChange পদ্ধতিটি অবশ্যই ওভাররাইড করা উচিত।

NavStateListDrawable নির্মাণের সময় আপনি যে আইকনটি প্রদর্শন করতে চান তার স্তরটি পার করতে হবে।

public class NavStateListDrawable extends StateListDrawable {

    private int level;

    public NavStateListDrawable(Context context, int level) {

        this.level = level;
        //int stateChecked = android.R.attr.state_checked;
        int stateFocused = android.R.attr.state_focused;
        int statePressed = android.R.attr.state_pressed;
        int stateSelected = android.R.attr.state_selected;

        addState(new int[]{ stateSelected      }, context.getResources().getDrawable(R.drawable.nav_btn_pressed));
        addState(new int[]{ statePressed      }, context.getResources().getDrawable(R.drawable.nav_btn_selected));
        addState(new int[]{ stateFocused      }, context.getResources().getDrawable(R.drawable.nav_btn_focused));

        addState(new int[]{-stateFocused, -statePressed, -stateSelected}, context.getResources().getDrawable(R.drawable.nav_btn_default));


    }

    @Override
    protected boolean onStateChange(int[] stateSet) {

        boolean nowstate = super.onStateChange(stateSet);

        try{
            LayerDrawable defaultDrawable = (LayerDrawable)this.getCurrent();


            LevelListDrawable bar2 =  (LevelListDrawable)defaultDrawable.findDrawableByLayerId(R.id.nav_icons);
            bar2.setLevel(level);
        }catch(Exception exception)
        {

        }

        return nowstate;
    }
}

বিভিন্ন নেভিগেশন বোতামের অঙ্কনযোগ্য রাষ্ট্রগুলির জন্য আমার নীচের মতো কিছু রয়েছে something

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

   <item android:drawable="@drawable/top_bar_default" >

   </item>

    <item android:id="@+id/nav_icons" android:bottom="0dip">
        <level-list xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:maxLevel="0" >
                <bitmap
                    android:src="@drawable/top_bar_icon_back"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="1" >
                <bitmap
                    android:src="@drawable/top_bar_icon_nav"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="2" >
                <bitmap
                    android:src="@drawable/top_bar_icon_settings"
                    android:gravity="center" />
            </item>
            <item android:maxLevel="3" >
                <bitmap
                    android:src="@drawable/top_bar_icon_search"
                    android:gravity="center" />
            </item>
        </level-list>

    </item>

</layer-list>

আমি এটি একটি প্রশ্ন এবং উত্তর হিসাবে পোস্ট করতে যাচ্ছিল, কিন্তু আপনি খুব প্রশ্ন জিজ্ঞাসা করা হিসাবে দেখে, আপনি এখানে যান। দ্রষ্টব্য, এটি আপনাকে প্রচুর পরিমাণে এক্সএমএল ফাইল সংজ্ঞায় বাঁচিয়ে রেখেছে। আমি প্রায় 50-100 এক্সএমএল সংজ্ঞা থেকে প্রায় 4 এ নেমে গেলাম !.


নাভস্টেটলিস্ট্র্যায়েবল কোড কার্যকরভাবে নির্বাচককে এক্সএমএলকে রিন্ডান্ট করে তোলে।
এমিল

হাই এমিলি, এমন কোনও সম্ভাবনা আছে যে কোনও কারণে কোনও বোতামের পটভূমি হিসাবে প্রথমবার দেখা যাবে না draw ব্যাকগ্রাউন্ডটি প্রদর্শিত হওয়ার জন্য বাটনটি সরিয়ে নিয়ে আবার ফিরে যেতে এবং ক্রিয়াকলাপটিতে ফিরে যেতে আমি যেখানে সমস্যাটি পেয়েছি সেদিকেই আমার সমস্যাটি হচ্ছে। (এটি কেবলমাত্র এইচডিপিআই স্ক্রিনে ঘটে তবে আমার এমডিপিআই-তে কাজ করে)। আমি বিশ্বাস করি অন্যেরও এই সমস্যা থাকতে পারে। আপনার কোডটি কি সমস্ত পর্দার ঘনত্বের জন্য পরীক্ষা করা হয়?
ryیوانstyron

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

ধন্যবাদ আমি জানি না আমি কী ভুল করছি কিন্তু শেষ পর্যন্ত আমার কাছে কেবল নিম্নলিখিতগুলি ছিল: বাটনস্টেটস = নতুন স্টেটলিস্টড্র্যাব্যাবল (); বাটনস্টেটস.এডিডিস্টেট (নতুন ইনট্রে [] {statePressed}, অ্যাপ্লিকেশন কনস্ট্যান্টস.মডিউলআইমেজলোডার.ফাইন্ডআইমেজবাইনেম (অঙ্কনযোগ্য_প্রেসড)); বাটনস্টেটস.এডিডিস্টেট (নতুন ইনট্রে [] state - স্টেটফোকসড, -স্টেটপ্রেসড, -স্টেটসিলেক্টড}, অ্যাপ্লিকেশন কনস্ট্যান্টস.মডিউলআইমেজলোয়াডার.ফাইন্ড আইমেজবাইনেম (অঙ্কনযোগ্য_সামান্য));
রাইভিয়ানস্টায়রন

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