Как использовать getChildAt () для ссылки на ImageView из LinearLayout - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь написать простой виджет, который является своего рода индикатором положения. Он отображает линию точек. Каждая из точек может принимать одно из двух состояний: активное или неактивное. Количество точек является переменным. Мне удалось написать функциональный виджет, используя массив ImageViews, который называется ivs []. Используются две отдельные переменные: dot_active. xml и dot_inactive. xml, переключение между которыми осуществляется с помощью метода .setImageDrawable(), циклически повторяющегося по элементам ivs []. Полный код, который будет работать, будет позже.

Мне интересно, можно ли получить тот же эффект без массива, просто получая элементы непосредственно из объекта LinearLayout. Я создал точку. xml.

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

    <item
        android:state_activated="true"
        android:drawable="@drawable/dot_active">
    </item>
    <item
        android:drawable="@drawable/dot_inactive">
    </item>

</selector>

Идея состоит в том, что я мог бы использовать что-то вроде linearLayout.getChildAt(k).setActivated(true);, чтобы изменить состояние точки. Я начал тестировать новый код, но заметил, что этот вид кода меняет все точки одновременно, а не одну. Кто-нибудь может предложить решение?

CODE1: Вот код, который делает то, что ожидается:

  public CustomWidget(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        final Context tmpContext = context;

        //number of dots to be displayed is max_n-1
        max_n = 6; 
        active_n = 0;

        vp3 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        vp4 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        vp3.setMargins(3,25,0,0);
        vp4.setMargins(0,25,0,0);

        LayoutInflater layoutInflater = LayoutInflater.from(context);
        layoutInflater.inflate(R.layout.custom_widget, this);

        linearLayout=(LinearLayout) findViewById(R.id.ll);
        res = getResources();
        drawable = res.getDrawable(R.drawable.dot);

        ivs = new ImageView[20]; //an array containing image views

        for(int i=0; i<(max_n-1); i++) {
            ivs[i] = new ImageView(context);
            ivs[i].setLayoutParams(vp3);
            ivs[i].setImageDrawable(drawable);
            linearLayout.addView(ivs[i]);
        }
        Log.d ("CUSTOM VIEW: ", "koniec generowania, tablica!");
    }

    //this method is called with a button and it activates the next dot
    public void changeImage(){

        ivs[active_n].setLayoutParams(vp3);
        ivs[active_n].setImageDrawable(res.getDrawable(R.drawable.dot_inactive));

        if (active_n<(max_n-2)){
            active_n++;
        }else{
            active_n=0;
        }

        ivs[active_n].setLayoutParams(vp4);
        ivs[active_n].setImageDrawable(res.getDrawable(R.drawable.dot_active));
    }

}

CODE2: Здесь это код, который не работает.

  public dotBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        final Context tmpContext = context;

        max_n =6;
        active_n = 0;
        vp3 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        vp4 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        vp3.setMargins(3,25,0,0);
        vp4.setMargins(0,25,0,0);

        LayoutInflater layoutInflater = LayoutInflater.from(context);
        layoutInflater.inflate(R.layout.custom_widget, this);

        linearLayout=(LinearLayout) findViewById(R.id.ll);
        Log.d("DOTBAR: ", linearLayout.getId()+"");
        Log.d("DOTBAR: ", " ");

        res = getResources();
        drawable = res.getDrawable(R.drawable.dot);

        for(int i=0; i<(max_n-1); i++) {
            addImage();
        }

    }

    public void addImage(){
        iv = new ImageView(this.getContext());
        iv.setImageDrawable(drawable);
        linearLayout.addView(iv,vp3);
    }

    //when called the method below was supposed to change the state of the k-th image, however
    //for k<>max_n-2 it does nothing visible and for k==max_n-2 it sets all dots active
    public void activateImage(){
        int k = 4;
        linearLayout.getChildAt(k).setActivated(true);
    }
}  

Можно ли изменить метод activImage () в CODE2, чтобы получить те же результаты, что и CODE1? Буду благодарен за любые предложения.

...