【Android】Android 自定義View 代碼複用

前言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>

就能夠實現自定義屬性。

以上就是全部的代碼,有什麼好的建議能夠留言,相互交流。 轉載請註明出處: 【定陶黃公子】

相關文章
相關標籤/搜索