Подтвердить что ты не робот

Android - прослушиватель OnClick в отдельном классе

Можно ли сделать дополнительный класс для хранения прослушивателя OnClick? Значение не создается в классе Activity?

Я просто считаю, что включение слушателей OnClick в основной класс активности просто беспорядочно, и я предпочел бы иметь их в отдельных классах. Благодаря

4b9b3361

Ответ 1

Конечно, это возможно. Просто создайте класс, реализующий View.OnClickListener, и установите его как слушателя в View. Например:

public class ExternalOnClickListener implements View.OnClickListener {

    public ExternalOnClickListener(...) {
        // keep references for your onClick logic 
    }

    @Override public void onClick(View v) {
        // TODO: add code here
    }

}

И затем установите экземпляр выше класса в качестве слушателя:

view.setOnClickListener(new ExternalOnClickListener(...));

Параметрированный конструктор не является обязательным, но, скорее всего, вам нужно будет что-то передать, чтобы на самом деле заставить логику onClick(...) работать.

Внедрение класса анонимно, как правило, проще работать. Просто мысль.

Ответ 2

Вместо того, чтобы помещать onCLicklistener в отдельный класс, почему вы не пытаетесь определить onCLicklistener вне onCreate()??

Например, например:

OnCreate()

yourViewName.setOnClicklistener(listener):

Снаружи onCreate()

private OnClickListener listener    =   new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

        }
    };

Ответ 3

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

MyListener listener = new MyListener(context, button, textView1, textView2, ratingBar, imageView);

Это тоже довольно громоздко. Если ваш слушатель прост, продолжайте и сделайте его отдельным классом. В противном случае, это зависит от вашей читаемости.

Ответ 4

Позвольте мне поделиться, как я кодирую это используя MVP. Это лучший способ сделать чистый код. Помните, что каждый класс должен иметь интерфейс для управления им. Я покажу вам самый простой.

Предположим, вы хотите добавить ToCxt к тексту и управлять им из другого класса. Вот как это работает. Создавать интерфейсы просто для связи друг с другом, и вы можете легко просмотреть код.

  1. Создайте интерфейс для этого класса MainActivity.

    public interface MainActivityView {
        void showToast();
    }
    
  2. Создайте другой интерфейс для класса Presenter.

    public interface IMainPresenter<V extends MainActivityView> {
        /*Generic Type is to make sure it comes from MainActivity class only and to avoid other class to access it.*/
        void onAttach(V mainView);
        void onButtonClick();
    }
    

Помните, что интерфейсы - это не что иное, как переопределение метода для каждого класса.

  1. Создайте класс Presenter

    public class MainPresenter<V extends MainActivityView> implements IMainPresenter<V> {
    
        private V mainActivityView;
    
        @Override
        public void onAttach(V mainActivityView) {
            this.mainActivityView=mainActivityView;
        }
    
        public V getView() {
            return mainActivityView;
        }
    
        @Override
        public void onButtonClick() {
            getView().showToast(); //This is the method from MainActivity controlling with this class
        }
    }
    
  2. Я пропущу макет Activity_main.xml, потому что там просто кнопка с id = "@+id/buttonId." В MainActivityClass,

    public class MainActivity extends AppCompactActivity implements MainActivityView {
    
    Button btn;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            MainPresenter mainPresenter = new MainPresenter();
            mainPresenter.onAttach(this);
    
            btn = findViewById(R.id.buttonId);
    
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mainPresenter.onButtonClick(); //Here, check No.3 again!
                }
             });
        }
    
        @Override
        public void showToast() {
             Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
        }
    }
    
  3. Все, что я хочу вам сказать, это. Если вы создаете объекты в классе, он не может выполнять модульное тестирование. Вот почему вы не видите никаких новых объектов, вызывающих в Android. Таким образом, вы можете использовать одноэлементный шаблон (вот ленивый тип) в классе Presenter. Я удалю его интерфейс и Generic, чтобы увидеть его четко.

    public class MainPresenter {
    
           private static final MainPresenter mainPresenter = new MainPresenter();
    
           MainPresenter() {}
    
           public static MainPresenter getInstance() {
                   return mainPresenter;
           }
    
           //Some methods here can be get it once you create an object with getInstance();
    }
    

И поэтому вы можете получить его методы из MainActivity следующим образом. Вместо создания подобных объектов...

    MainPresenter mainPresenter = new MainPresenter();

Вы можете получить это так...

    MainPresenter mainPresenter = mainPresenter.getInstance();

Больше примеров для одноэлементного шаблона можно найти здесь, https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples

  1. Наконец, использование static не очень хороший выбор, потому что он использует пространство памяти независимо от того, используете вы его или нет. И так, вы можете создавать объекты в Application Layer, получать его с помощью Typecasting. Я уверен, что вам не нужно тестировать модуль на этом прикладном уровне.

    public class AppLayer extends Application {
    
        private MainPresenter mainPresenter;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            mainPresenter = new MainPresenter();
        }
    
        public MainPresenter getMainPresenter() {
            return mainPresenter;  
        }
    

И вам нужно дать имя класса в приложении в manifest.xml

    <application
    android:name=".AppLayer"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    </application>

И вы можете получить его с помощью Typecast в MainActivity, как это!

    MainPresenter mainPresenter = ((AppLayer)getApplication()).getMainPresenter();
  1. Для дальнейшего изучения, я предлагаю вам изучить принципы ButterKnife, Dagger 2 и SOLID. Это поможет вам создать чистое кодирование. Веселиться!

Ответ 5

Вы можете это сделать. Но просто подумайте, что у вас не будет ссылки на деятельность, ни на ее атрибуты, в том числе на все представления. (если вы не сделаете их общедоступными или доступными с помощью методов getters).

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

Ответ 6

public class CommonClick {
    public static  void commonClick(final AppCompatActivity context){
        context.findViewById(R.id.appbar).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }
}