Android - прослушиватель OnClick в отдельном классе
Можно ли сделать дополнительный класс для хранения прослушивателя OnClick? Значение не создается в классе Activity?
Я просто считаю, что включение слушателей OnClick в основной класс активности просто беспорядочно, и я предпочел бы иметь их в отдельных классах. Благодаря
Ответы
Ответ 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 к тексту и управлять им из другого класса. Вот как это работает. Создавать интерфейсы просто для связи друг с другом, и вы можете легко просмотреть код.
Создайте интерфейс для этого класса MainActivity.
public interface MainActivityView {
void showToast();
}
Создайте другой интерфейс для класса 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();
}
Помните, что интерфейсы - это не что иное, как переопределение метода для каждого класса.
Создайте класс 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
}
}
Я пропущу макет 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();
}
}
Все, что я хочу вам сказать, это. Если вы создаете объекты в классе, он не может выполнять модульное тестирование. Вот почему вы не видите никаких новых объектов, вызывающих в 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
Наконец, использование 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();
- Для дальнейшего изучения, я предлагаю вам изучить принципы 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) {
}
});
}
}