前言java
在写程序的时候,咱们不少时候士想着怎么去尽可能的少写代码,那么代码的复用就显着尤其重要,在一个地方写了以后,其余地方也可以复用是更好的事情,那么今天咱们就简单的介绍代码的复用。android
那么咱们就以一个登录界面为例,来简单的演示代码的复用。app
实例项目就是一个简单的登陆和注册的界面,实现代码复用,修改的时候简单的修改布局就能够实现。ide
首先咱们先建立一个继承LinearLayout为基类的View,名字咱们命名为LoginView。布局
代码以下:this
public class LoginView extends LinearLayout { private Context mContext; public LoginView(Context context) { this(context); } public LoginView(Context context, AttributeSet attrs) { super(context, attrs); mContext= context; //... } }
在上面的代码中咱们定义一个mContext成员变量,在这边咱们后面会使用到。code
接下来建立主要的布局(login_view.xml):orm
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <EditText android:id="@+id/userName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="User name" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Password" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/loginButton" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Login" /> <Button android:id="@+id/signupButton" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Sign Up" /> </LinearLayout> </LinearLayout>
布局就是上面的样子很简单,咱们就不作过多的说明了。xml
那么接下来咱们就把咱们本身定义的这个LoginView做为控件使用到咱们MainActivity的主布局(activity_main.xml)中去,代码以下:继承
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingTop="60dp" android:fitsSystemWindows="true" tools:context=".activity.MainActivity" tools:showIn="@layout/activity_main"> <com.zhjy.hxf.hzloginview.view.LoginView android:id="@+id/loginView" app:UserNameHint="yo bro" app:PasswordHint="hey wsp" android:layout_width="match_parent" android:layout_height="match_parent"> </com.zhjy.hxf.hzloginview.view.LoginView> </LinearLayout>
com.zhjy.hxf.hzloginview.view.LoginView就是这个View的全名称,同时咱们给这个LoginView指定了id为loginView。在MainActivity的java文件中能够取到这个View:
mLoginView = (LoginView)findViewById(R.id.loginView);
这个时候能够run起来这个项目。but,这样又有什么卵用呢?点个按钮也没什么反应。是的,咱们须要给这个组合控件添加代码。咱们须要从布局文件中解析出这些单独的控件,EditText和Button。就像是在Activity中常常作的那样:
View view = LayoutInflater.from(mContext).inflate(R.layout.login_view, this, true); EditText userName = (EditText)view.findViewById(R.id.userName); EditText password = (EditText)view.findViewById(R.id.password); Button loginButton =(Button)view.findViewById(R.id.loginButton); Button signupButton = (Button) view.findViewById(R.id.signupButton)
给按钮设置Click Listener。首先让按钮能有反应。那么须要一个OnClickListener。咱们这里只有两个按钮,因此只要在类的级别设定出监听器就能够:
public class LoginView extends LinearLayout implements View.OnClickListener{ private Context mContext; private OnLoginViewClickListener onLoginViewClickListener; public LoginView(Context context) { super(context); } public LoginView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; init(attrs); } private void init(AttributeSet attrs) { View view = LayoutInflater.from(mContext).inflate(R.layout.login_view, this, true); EditText userName = (EditText) view.findViewById(R.id.userName); EditText password = (EditText) view.findViewById(R.id.password); Button loginButton = (Button) view.findViewById(R.id.loginButton); Button signupButton = (Button) view.findViewById(R.id.signupButton); loginButton.setOnClickListener(this); signupButton.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.loginButton) { Toast.makeText(MainActivity.this, "Login", Toast.LENGTH_LONG).show(); } else if (v.getId() == R.id.signupButton) { Toast.makeText(MainActivity.this, "Register", Toast.LENGTH_LONG).show(); } }
如今运行一下就能够实现Toast的显示效果了。
以上代码是全部功能都在View中进行实现了,那么咱们怎么去实现代码的复用呢,显然是很差的,咱们得想办法在Activity去实现这个功能。
那么就定义一个接口,去实现这个功能,大概的过程是这样:
1. 控件中定义接口。 2. 在Activity的实现。 3. 在控件中使用activity的实现。
这里咱们定义了接口 public interface OnLoginViewClickListener 还有这么一个方法 void loginViewButtonClicked(View v);
public class LoginView extends LinearLayout implements View.OnClickListener { private Context _context; //... @Override public void onClick(View v) { //... } public void setOnLoginViewClickListener(OnLoginViewClickListener loginViewClickListener) { //... } public interface OnLoginViewClickListener { void loginViewButtonClicked(View v); } }
下面在activity中实现这个接口(这个在java里比在ObjC里简单多了好吗),那么咱们就把全部的代码都贴出来。
MainActivity.java
public class MainActivity extends AppCompatActivity { private LoginView mLoginView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); initView(); } private void initView() { mLoginView = (LoginView)findViewById(R.id.loginView); /** * 而后拿到这边的接口方法 */ mLoginView.setOnLoginViewClickListener(new LoginView.OnLoginViewClickListener() { @Override public void loginViewButtonClicked(View v) { if (v.getId() == R.id.loginButton){ Toast.makeText(MainActivity.this, "Login", Toast.LENGTH_SHORT).show(); }else if(v.getId() == R.id.signupButton){ Toast.makeText(MainActivity.this,"Register", Toast.LENGTH_SHORT).show(); } } }); } }
LoginView.java
** * @author :huangxianfeng on 2016/12/16. * 自定义LoginView实现组件代码复用 */ public class LoginView extends LinearLayout implements View.OnClickListener { private Context mContext; private OnLoginViewClickListener onLoginViewClickListener; public LoginView(Context context) { super(context); } public LoginView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; init(attrs); } private void init(AttributeSet attrs) { View view = LayoutInflater.from(mContext).inflate(R.layout.login_view, this, true); EditText userName = (EditText) view.findViewById(R.id.userName); EditText password = (EditText) view.findViewById(R.id.password); Button loginButton = (Button) view.findViewById(R.id.loginButton); Button signupButton = (Button) view.findViewById(R.id.signupButton); //设置hint属性 TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.LoginView); CharSequence userNameHint = typedArray.getText(R.styleable.LoginView_UserNameHint); CharSequence passwordHint = typedArray.getText(R.styleable.LoginView_PasswordHint); userName.setHint(userNameHint); password.setHint(passwordHint); loginButton.setOnClickListener(this); signupButton.setOnClickListener(this); } @Override public void onClick(View v) { if (onLoginViewClickListener != null) { onLoginViewClickListener.loginViewButtonClicked(v); } } public void setOnLoginViewClickListener(OnLoginViewClickListener loginViewClickListener) { onLoginViewClickListener = loginViewClickListener; } public interface OnLoginViewClickListener { void loginViewButtonClicked(View v); } }
在上面的代码中还有一个自定义hint属性的代码,在values中定义一个attrs.xml文件:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="LoginView"> <attr name="UserNameHint" format="string"/> <attr name="PasswordHint" format="string"/> </declare-styleable> </resources>
就能够实现自定义属性。
以上就是全部的代码,有什么好的建议能够留言,相互交流。 转载请注明出处: 【定陶黄公子】