Как сократить findViewById и setOnClickListener для похожих кнопок?

#java #android

#java #Android

Вопрос:

Есть ли способ сократить код, если у вас много кнопок с аналогичным использованием? Должны быть способы, однако я еще недостаточно опытен, чтобы придумать другое решение. Возьмем, к примеру, следующий код:

     btn_0 = findViewById(R.id.btn_0);
    btn_1 = findViewById(R.id.btn_1);
    btn_2 = findViewById(R.id.btn_2);
    btn_3 = findViewById(R.id.btn_3);
    btn_4 = findViewById(R.id.btn_4);
    btn_5 = findViewById(R.id.btn_5);

    btn_0.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText("0");
            function();
        }
    });

    btn_1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText("1");
            function();
        }
    });

    btn_2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText("2");
            function();
        }
    });

    btn_3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText("3");
            function();
        }
    });

    btn_4.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText("4");
            function();
        }
    });

    btn_5.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText("5");
            function();
        }
    });
 

Какие есть варианты, чтобы написать это более эффективно и с меньшим количеством повторяющегося кода? Я видел такой вариант, однако я понятия не имею, как это работает на самом деле:

     private Button[] btns = new Button[4];

for (int i = 0; i < 4; i  ) {
    this.btns[i] = super.findViewById(new int[]{R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4}[i]);
}
 

Если вы предложите решение, я был бы очень признателен за краткое объяснение, почему этот способ работает. Спасибо за ваши усилия 🙂

Ответ №1:

Если вы просто хотите избежать принципа DRY (не повторяйтесь), вы можете создать прослушиватель в функции и передать text параметр типа:

 View.OnClickListener createOnClickListener(String text) {
  new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            view_input.setText(text);
            function();
        }
    }
}
 

Пример использования

 btn_4.setOnClickListener(createOnClickListener("4"))
 

Ответ №2:

Рассмотрите привязку к просмотру, если вам особенно надоело делать findViewById :

из примеров документов это позволяет вам сделать что-то вроде этого

 private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});
 

Ответ №3:

Мы используем https://jakewharton.github.io/butterknife / итак, мы можем написать это

 @OnClick({R.id.button0,R.id.button1,R.id.button2,R.id.button3,R.id.button4})
  public void setText(View view){
      switch(view.getId()){
         case R.id.button0:
             break;
         .....
         .....
      }
  }
 

Комментарии:

1. хотя мне нравится внешний вид этого, необходимость полагаться на стороннюю библиотеку для достижения этой цели мне не кажется замечательной, учитывая, что это может быть просто массив, который вы перебираете

Ответ №4:

Вы можете использовать привязку к представлению, если ваша конечная цель — избежать findviewbyid() .

https://developer.android.com/topic/libraries/view-binding

Проверьте эту ссылку для просмотра официальной документации привязки.

Комментарии:

1. да, у меня была та же идея, когда я писал свой ответ