是否可以创建一个二级类来保存OnClick侦听器?意义没有在Activity类中创建?
我只是发现在主活动类中放置OnClick监听器只是凌乱,我宁愿将它们放在不同的类中。感谢
答案 0 :(得分:29)
当然,那是可能的。只需创建一个实现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(...)
逻辑工作。
通过匿名实现类通常更容易使用。只是一个想法。
答案 1 :(得分:10)
不要将onCLicklistener
放在单独的类中,为什么不尝试在onClickListener
之外定义onCreate()
?
例如:像这样
<强>的onCreate()强>
yourViewName.setOnClicklistener(listener):
外部onCreate()
private OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
};
答案 2 :(得分:5)
是的,你可以。但是,使侦听器成为内部类有一个优点 - 它可以直接访问活动类的字段和变量。如果你把它作为一个单独的类,并且你的监听器实际上需要访问5个视图,那么你的监听器构造函数可能如下所示:
MyListener listener = new MyListener(context, button, textView1, textView2, ratingBar, imageView);
这也有点笨重。如果您的听众很简单,请继续将其作为单独的课程。否则,由您提供可读性。
答案 3 :(得分:1)
你可以做到。但只是认为你不会参与活动,也不会参考它的属性,包括所有视图。 (除非您将它们公开或使用getter方法访问)。
另外,要特别注意存储对活动或侦听器上任何成员的引用,因为它们可能会避免垃圾收集器重新获取侦听器内存。
答案 4 :(得分:0)
让我分享一下我如何使用MVP进行编码。这是编写清晰代码的最佳方法。请记住,每个类都必须具有控制它的接口。我将向您展示最简单的一个。
假设您要烘烤文本onClick并从另一个类控制它。运作方式如下。创建界面无非是要相互连接,您可以轻松查看代码。
为该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().onToast(); //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类中使用单例模式(这是惰性类型)。我将删除其接口和“通用”以使其清晰可见。
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 object with getInstance();
}
因此您可以像这样从MainActivity获取其方法。 而不是像这样创建对象...
MainPresenter mainPresenter = new MainPresenter();
您可以这样获得它...
MainPresenter mainPresenter = mainPresenter.getInstance();
有关单例模式的更多示例,请参见此处, https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
最后,使用静态不是一个很好的选择,因为无论您是否使用它,它都会使用内存空间。因此,您可以在应用程序层中创建对象,并通过类型转换将其获取。我确定您不需要对该应用程序层进行单元测试。
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中提供一个类名
<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>
您可以通过MainActivity中的Typecast来获得它!
MainPresenter mainPresenter = ((AppLayer)getApplication()).getMainPresenter();
答案 5 :(得分:0)
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) {
}
});
}
}