前言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>
就能夠實現自定義屬性。
以上就是全部的代碼,有什麼好的建議能夠留言,相互交流。 轉載請註明出處: 【定陶黃公子】