แทนที่รูปภาพตัวเลือกโดยใช้โปรแกรม


116

ฉันมี ImageView ที่มีทรัพยากรรูปภาพที่วาดได้ซึ่งตั้งค่าเป็นตัวเลือก ฉันจะเข้าถึงตัวเลือกโดยใช้โปรแกรมและเปลี่ยนภาพของสถานะที่ไฮไลต์และไม่ไฮไลต์ได้อย่างไร

นี่คือรหัสของตัวเลือก:

<?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ด้วยรูปภาพอื่น ๆ


มันจะง่ายกว่าไหมหากมีตัวเลือกสองตัวและสลับกัน
bigstones

2
ปัญหาคือคุณสามารถจบลงด้วยไฟล์ xml หลายร้อยไฟล์
Emile

คำตอบ:


245

เท่าที่ฉันสามารถหาได้ (ฉันได้ลองทำสิ่งที่คล้ายกันด้วยตัวเอง) ไม่มีวิธีใดที่จะแก้ไขสถานะเดียวหลังจากที่กำหนด StateListDrawable แล้ว อย่างไรก็ตามคุณสามารถกำหนดรหัสใหม่ได้:

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
ฉันไม่สามารถเพิ่มสิ่งนี้ลงในมุมมองภาพได้ setState ไม่พร้อมใช้งาน
dropsOfJupiter

2
จริงๆแล้วฉันพบมัน setImageDrawable () ขอบคุณมากมันใช้งานได้และช่วยฉันได้ประมาณ 40 ไฟล์ xml!
dropsOfJupiter

2
ดังนั้นฉันจึงมีบันทึกอื่นที่เกี่ยวข้องกับเรื่องนี้ ฉันหวังว่าคุณจะตอบได้ ฉันตั้งค่าตัวเลือกนี้ใน ImageView ที่อยู่ใน Custom Control การควบคุมแบบกำหนดเองยังมีตัวเลือกเป็นพื้นหลัง ดังนั้นตัวเลือกของการควบคุมทั้งหมดจึงทำงานได้ในขณะที่ตัวเลือก ImageView ไม่ทำงาน มีบางอย่างที่ฉันทำผิด? มีลำดับหรือไม่
dropsOfJupiter

1
ยินดีต้อนรับ! ใช่ฉันไม่รู้ว่าทำไมฉันถึงใส่ setState ควร setImageDrawable คุณพูดถูก ตามคำถามอื่น ๆ ของคุณฉันขอแนะนำให้โพสต์คำถามใหม่พร้อมรหัสสำหรับการควบคุมที่กำหนดเองและตัวเลือกของคุณฉันไม่แน่ใจในคำตอบสำหรับสิ่งนั้น
Kevin Coppock

3
ฉันใช้รหัสเดียวกัน รูปภาพที่ฉันระบุไว้ใน ----> new int [] {} จะยังคงอยู่เสมอ ฉันผิดตรงไหน ??
KK_07k11A0585

6

ฉันมีปัญหาเดียวกันและไปอีกขั้นเพื่อแก้ปัญหา อย่างไรก็ตามปัญหาเดียวคือคุณไม่สามารถระบุ NavStateListDrawable ใน xml ได้ดังนั้นคุณต้องตั้งค่าพื้นหลังขององค์ประกอบ UI ของคุณผ่านโค้ด จากนั้นเมธอด onStateChange จะต้องถูกแทนที่เพื่อให้แน่ใจว่าทุกครั้งที่มีการเปลี่ยนแปลงระดับของ main drawable คุณจะต้องอัปเดตระดับของรายการระดับรองด้วย

เมื่อสร้าง 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;
    }
}

สำหรับสถานะที่วาดได้ของปุ่มนำทางที่แตกต่างกันทั้งหมดฉันมีสิ่งต่อไปนี้

<?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>

ฉันกำลังจะโพสต์สิ่งนี้เป็นคำถามและคำตอบ แต่เมื่อคุณถามคำถามนั้นแล้วคุณไปได้เลย หมายเหตุสิ่งนี้ช่วยให้คุณประหยัดค่านิยามไฟล์ xml จำนวนมาก ฉันลดจากคำจำกัดความ 50-100 xml ลงเหลือประมาณ 4!


navstatelistdrawable code ทำให้ตัวเลือก xml ซ้ำซ้อนได้อย่างมีประสิทธิภาพ
Emile

สวัสดีเอมิลีมีความเป็นไปได้หรือไม่ที่สิ่งที่วาดเป็นพื้นหลังปุ่มจะไม่ปรากฏในครั้งแรกไม่ว่าด้วยเหตุผลใดก็ตาม ขณะนี้ฉันพบปัญหาที่ต้องแตะบริเวณปุ่มเพื่อให้พื้นหลังแสดงหรือปิดและเปลี่ยนกลับไปที่กิจกรรม (สิ่งนี้เกิดขึ้นเฉพาะบนหน้าจอ hdpi แต่ทำงานได้ดีบน mdpi ของฉัน) ฉันเชื่อว่าคนอื่น ๆ ก็อาจมีปัญหานี้เช่นกัน รหัสของคุณได้รับการทดสอบความหนาแน่นของหน้าจอทั้งหมดหรือไม่
ryvianstyron

สวัสดีไม่นี่เป็นบทความที่เขียนขึ้นในขณะที่ย้อนกลับไปและเป็นเพียงอุปกรณ์เดียวในเวลานั้น ฉันไม่แน่ใจว่าปัญหาประเภทใดที่อาจเกิดขึ้นแม้ว่าฉันจะทราบว่าความหนาแน่นของหน้าจอและเค้าโครงหลายหน้าจอไม่ควรมีปัญหา
Emile

ขอบคุณฉันไม่รู้ว่าฉันทำอะไรผิด แต่ในที่สุดฉันก็มีสิ่งต่อไปนี้: buttonStates = new StateListDrawable (); buttonStates.addState (int ใหม่ [] {statePressed}, ApplicationConstants.moduleImageLoader.findImageByName (drawable_pressed)); buttonStates.addState (int [] ใหม่ {- stateFocused, -statePressed, -stateSelected}, ApplicationConstants.moduleImageLoader.findImageByName (drawable_normal));
ryvianstyron

1
นี่เป็นที่แรกที่ฉันเห็นว่าต้องใช้ค่าลบสำหรับสถานะที่ตั้งค่าเป็นเท็จ เอกสารประกอบยังไม่ชัดเจนเกี่ยวกับเรื่องนี้ ขอบคุณสำหรับทิป!
eocanha
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.