功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼
前言
一個(gè)好的應(yīng)用需要一個(gè)有良好的用戶體驗(yàn)的登錄界面,現(xiàn)如今,許多應(yīng)用的的登錄界面都有著用戶名,密碼一鍵刪除,用戶名,密碼為空提示,以及需要輸入驗(yàn)證碼的功能??粗鴆sdn上的大牛們的文章,心里想著也寫一個(gè)登錄界面學(xué)習(xí)學(xué)習(xí),許多東西都是參考別的文章,綜合起來的。廢話少說,接下來看看是如何實(shí)現(xiàn)的。
ps:由于懶得摳圖。所以程序的圖標(biāo)很難看。
程序運(yùn)行時(shí)的圖示:
首先是布局文件沒有什么難度。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ImageView android:id="@+id/tv_login" android:src="@drawable/ic_launcher" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:gravity="center" /> <com.example.administrator.texttest.DeletableEditText android:id="@+id/tv_user" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30dp" android:layout_below="@id/tv_login" android:drawableLeft="@drawable/ic_launcher" android:drawableRight="@drawable/ic_launcher" android:hint="請(qǐng)輸入賬戶" android:ems="10"/> <com.example.administrator.texttest.DeletableEditText android:id="@+id/tv_psd" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30dp" android:layout_below="@id/tv_user" android:drawableLeft="@drawable/ic_launcher" android:drawableRight="@drawable/ic_launcher" android:hint="請(qǐng)輸入密碼" android:inputType="textPassword" android:ems="10"/> <LinearLayout android:id="@+id/lyYanzhengma" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/tv_psd"> <LinearLayout android:id="@+id/lyVerify" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/tvHideA" android:layout_width="70dp" android:layout_height="70dp" android:visibility="gone" android:gravity="center" android:textSize="30dp" /> <TextView android:id="@+id/tvHideB" android:layout_width="70dp" android:layout_height="70dp" android:visibility="gone" android:gravity="center" android:textSize="30dp" /> <TextView android:id="@+id/tvHideC" android:layout_width="70dp" android:layout_height="70dp" android:visibility="gone" android:gravity="center" android:textSize="30dp" /> <TextView android:id="@+id/tvHideD" android:layout_width="70dp" android:layout_height="70dp" android:visibility="gone" android:gravity="center" android:textSize="30dp" /> </LinearLayout> <LinearLayout android:id="@+id/IV_num" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:layout_height="70dp" android:layout_width="50dp" android:id="@+id/ivNumA"/> <ImageView android:layout_height="70dp" android:layout_width="50dp" android:id="@+id/ivNumB"/> <ImageView android:layout_height="70dp" android:layout_width="50dp" android:id="@+id/ivNumC"/> <ImageView android:layout_height="70dp" android:layout_width="50dp" android:id="@+id/ivNumD"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_height="wrap_content" android:layout_width="match_parent"> <EditText android:layout_height="wrap_content" android:layout_width="120dp" android:textSize="30dp" android:id="@+id/etCheck" android:maxLength="4" android:singleLine="true" android:hint="驗(yàn)證碼"/> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="結(jié)果" android:id="@+id/tvCheck" android:textSize="30dp" android:visibility="gone"/> </LinearLayout> </LinearLayout> <Button android:id="@+id/bt_login" android:text="登 錄" android:textSize="30dp" android:layout_below="@id/lyYanzhengma" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
然后是加載一些布局文件,和一些控件的初始化
//登錄按鈕 private Button btLogin; //賬戶 private DeletableEditText userEditText; //密碼 private DeletableEditText psdEditText; //驗(yàn)證碼的數(shù)字文本 private TextView tvHideA,tvHideB,tvHideC,tvHideD; //驗(yàn)證碼的圖片文本 private ImageView ivNumA,ivNumB,ivNumC,ivNumD; //驗(yàn)證碼輸入文本 private EditText etCheck; //驗(yàn)證碼的檢測(cè)顯示文本 private TextView tvCheck; //存儲(chǔ)每個(gè)驗(yàn)證碼的數(shù)字 private String numStrTmp = ""; //存儲(chǔ)整個(gè)驗(yàn)證碼的數(shù)字 private String numStr = ""; //存儲(chǔ)驗(yàn)證碼的數(shù)組 private int[] numArray = new int[4]; //存儲(chǔ)顏色的數(shù)組 private int[] colorArray = new int[6]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupViews(); } private void setupViews() { btLogin = (Button) findViewById(R.id.bt_login); btLogin.setOnClickListener(new OnClickListenerImpl()); userEditText = (DeletableEditText) findViewById(R.id.tv_user); psdEditText = (DeletableEditText) findViewById(R.id.tv_psd); tvHideA = (TextView) findViewById(R.id.tvHideA); tvHideB = (TextView) findViewById(R.id.tvHideB); tvHideC = (TextView) findViewById(R.id.tvHideC); tvHideD = (TextView) findViewById(R.id.tvHideD); ivNumA = (ImageView) findViewById(R.id.ivNumA); ivNumB = (ImageView) findViewById(R.id.ivNumB); ivNumC = (ImageView) findViewById(R.id.ivNumC); ivNumD = (ImageView) findViewById(R.id.ivNumD); ivNumA.setOnClickListener(new OnClickListenerImpl()); ivNumB.setOnClickListener(new OnClickListenerImpl()); ivNumC.setOnClickListener(new OnClickListenerImpl()); ivNumD.setOnClickListener(new OnClickListenerImpl()); tvCheck = (TextView) findViewById(R.id.tvCheck); etCheck = (EditText) findViewById(R.id.etCheck); setNum();
自定義EditText的實(shí)現(xiàn)過程:
思路:設(shè)置兩個(gè)EidtText,在這個(gè)EditText中各設(shè)置圖標(biāo)。左邊圖標(biāo)為賬戶和密碼的圖標(biāo)提示,右邊圖標(biāo)為一鍵刪除 。因?yàn)镋ditText中的圖標(biāo)沒有onClick事件,為了實(shí)現(xiàn)點(diǎn)擊一鍵刪除效果所以要使用OnTouchEvent回調(diào)方法,監(jiān)聽點(diǎn)擊事件來判斷實(shí)現(xiàn)一鍵刪除。當(dāng)賬戶和密碼沒有字符時(shí),右邊的一鍵刪除圖標(biāo)設(shè)置隱藏,當(dāng)有字符時(shí),設(shè)置圖標(biāo)顯示。當(dāng)點(diǎn)擊到右邊圖標(biāo)范圍時(shí),刪除所在行的字符。從而實(shí)現(xiàn)一鍵刪除。 此外,當(dāng)賬戶和密碼為空而要登錄時(shí)。這兩行抖動(dòng)提示。
廢話不多說,直接上代碼注釋很清楚。
package com.example.administrator.texttest; import android.content.Context; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.CycleInterpolator; import android.view.animation.TranslateAnimation; import android.widget.EditText; /** * Created by Administrator on 2015-10-10. */ public class DeletableEditText extends EditText { private Drawable mRightDrawable; private boolean isHasFocus; public DeletableEditText(Context context) { this(context, null); } public DeletableEditText(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.editTextStyle); } public DeletableEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setupViews(); } private void setupViews() { //取的view的上下左右邊距 Drawable[] drawables = this.getCompoundDrawables(); // 取得right位置的Drawable // 即我們?cè)诓季治募性O(shè)置的android:drawableRight mRightDrawable = drawables[2]; // 設(shè)置焦點(diǎn)變化的監(jiān)聽 this.setOnFocusChangeListener(new FocusChangeListenerImpl()); // 設(shè)置EditText文字變化的監(jiān)聽 this.addTextChangedListener(new TextWatcherImpl()); // 初始化時(shí)讓右邊clean圖標(biāo)不可見 setClearDrawableVisible(false); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { //當(dāng)點(diǎn)擊松開時(shí)判斷點(diǎn)擊的位置。這里只進(jìn)行了X軸方向的判斷。 case MotionEvent.ACTION_UP: //判斷是否點(diǎn)擊到了右邊的圖標(biāo)區(qū)域 boolean isClean = (event.getX() > (getWidth() - getTotalPaddingRight())) && (event.getX() < (getWidth() - getPaddingRight())); if (isClean) { //清除字符 setText(""); } break; default: break; } return super.onTouchEvent(event); } private class FocusChangeListenerImpl implements OnFocusChangeListener { @Override public void onFocusChange(View v, boolean hasFocus) { isHasFocus = hasFocus; if (isHasFocus) { boolean isVisible = getText().toString().length() >= 1; setClearDrawableVisible(isVisible); } else { setClearDrawableVisible(false); } } } // 當(dāng)輸入結(jié)束后判斷是否顯示右邊clean的圖標(biāo) private class TextWatcherImpl implements TextWatcher { @Override public void afterTextChanged(Editable s) { //當(dāng)有字符時(shí)為true boolean isVisible = getText().toString().length() >= 1; //顯示右邊的圖標(biāo) setClearDrawableVisible(isVisible); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } } // 隱藏或顯示右邊clean的圖標(biāo) protected void setClearDrawableVisible(boolean isVisible) { Drawable rightDrawable; if (isVisible) { rightDrawable = mRightDrawable; } else { rightDrawable = null; } // 使用代碼設(shè)置該控件right處的圖標(biāo) setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], rightDrawable, getCompoundDrawables()[3]); } // 顯示動(dòng)畫 public void setShakeAnimation() { this.startAnimation(shakeAnimation(5)); } // CycleTimes動(dòng)畫重復(fù)的次數(shù) public Animation shakeAnimation(int CycleTimes) { //設(shè)置偏移動(dòng)畫 其中new TranslateAnimation(0,10,0,10)四個(gè)值表示為 X坐標(biāo)從0-->10,Y坐標(biāo)從0-->10 Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10); //設(shè)置動(dòng)畫次數(shù) translateAnimation.setInterpolator(new CycleInterpolator(CycleTimes)); //設(shè)置動(dòng)畫間隔 translateAnimation.setDuration(1000); return translateAnimation; } }
其中需要注意的知識(shí):
1.Drawable[] drawables = this.getCompoundDrawables(); 得到此View的 drawable. getCompoundDrawables()方法得到的有4個(gè)Drawable對(duì)象,分別對(duì)應(yīng)此View的左,上,右,下的邊距
2.boolean isClean = (event.getX() > (getWidth() - getTotalPaddingRight()))&& (event.getX() < (getWidth() - getPaddingRight())); 判斷點(diǎn)擊的區(qū)域是否為右邊圖標(biāo)范圍。其中event.getX()為點(diǎn)擊的位置的X坐標(biāo)大小。詳細(xì)如下圖所示:
3.Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10); 設(shè)置偏移動(dòng)畫 其中new TranslateAnimation(0,10,0,10)四個(gè)值表示為 X坐標(biāo)從0-->10,Y坐標(biāo)從0-->10
4.this.setOnFocusChangeListener(new FocusChangeListenerImpl());設(shè)置焦點(diǎn)變化的目的是為了更人性化。當(dāng)焦點(diǎn)在此行并且有字符時(shí)才顯示一鍵刪除圖標(biāo)。不在此行時(shí)圖標(biāo)隱藏。
5.this.addTextChangedListener(new TextWatcherImpl()); 設(shè)置text變化監(jiān)聽。new TextWatcher{}中有3個(gè)方法。分別是:
1).public void beforeTextChanged(CharSequence s, int start, int count,int after) {}
2).public void onTextChanged(CharSequence s, int start, int before,int count) {}
3).public void afterTextChanged(Editable s) {}
我們只需要在afterTextChanged(){Editable s}{}中添加要實(shí)現(xiàn)的方法即可。當(dāng)監(jiān)聽到text變化時(shí),設(shè)置右邊圖標(biāo)顯示。
TextWatcher { @Override public void afterTextChanged(Editable s) { //當(dāng)有字符時(shí)為true boolean isVisible = getText().toString().length() >= 1; //顯示右邊的圖標(biāo) setClearDrawableVisible(isVisible); }
驗(yàn)證碼的實(shí)現(xiàn)過程:
思路:設(shè)置4個(gè)ImageView。 首先隨機(jī)生成4個(gè)10以內(nèi)的數(shù)字存儲(chǔ)在數(shù)組里。并且記錄整個(gè)驗(yàn)證碼。在利用Bitmap.createBitmap方法講這4個(gè)數(shù)字轉(zhuǎn)化為圖片并且設(shè)置隨機(jī)顏色。每個(gè)數(shù)字圖片轉(zhuǎn)化的時(shí)候在隨機(jī)設(shè)置旋轉(zhuǎn)角度使這4個(gè)數(shù)字圖標(biāo)傾斜一定的角度。 驗(yàn)證碼就生成了。
驗(yàn)證驗(yàn)證碼的過程只是模擬下: 將輸入的驗(yàn)證碼跟記錄的驗(yàn)證碼作比較。相同 提示正確,不同提示錯(cuò)誤。并且重置驗(yàn)證碼。
點(diǎn)擊驗(yàn)證碼圖片區(qū)域也會(huì)重置驗(yàn)證碼。
代碼的注釋很詳細(xì)。上代碼~~~~:
package com.example.administrator.texttest; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import java.util.Random; public class MainActivity extends AppCompatActivity { //登錄按鈕 private Button btLogin; //賬戶 private DeletableEditText userEditText; //密碼 private DeletableEditText psdEditText; //驗(yàn)證碼的數(shù)字文本 private TextView tvHideA,tvHideB,tvHideC,tvHideD; //驗(yàn)證碼的圖片文本 private ImageView ivNumA,ivNumB,ivNumC,ivNumD; //驗(yàn)證碼輸入文本 private EditText etCheck; //驗(yàn)證碼的檢測(cè)顯示文本 private TextView tvCheck; //存儲(chǔ)每個(gè)驗(yàn)證碼的數(shù)字 private String numStrTmp = ""; //存儲(chǔ)整個(gè)驗(yàn)證碼的數(shù)字 private String numStr = ""; //存儲(chǔ)驗(yàn)證碼的數(shù)組 private int[] numArray = new int[4]; //存儲(chǔ)顏色的數(shù)組 private int[] colorArray = new int[6]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupViews(); } private void setupViews() { btLogin = (Button) findViewById(R.id.bt_login); btLogin.setOnClickListener(new OnClickListenerImpl()); userEditText = (DeletableEditText) findViewById(R.id.tv_user); psdEditText = (DeletableEditText) findViewById(R.id.tv_psd); tvHideA = (TextView) findViewById(R.id.tvHideA); tvHideB = (TextView) findViewById(R.id.tvHideB); tvHideC = (TextView) findViewById(R.id.tvHideC); tvHideD = (TextView) findViewById(R.id.tvHideD); ivNumA = (ImageView) findViewById(R.id.ivNumA); ivNumB = (ImageView) findViewById(R.id.ivNumB); ivNumC = (ImageView) findViewById(R.id.ivNumC); ivNumD = (ImageView) findViewById(R.id.ivNumD); ivNumA.setOnClickListener(new OnClickListenerImpl()); ivNumB.setOnClickListener(new OnClickListenerImpl()); ivNumC.setOnClickListener(new OnClickListenerImpl()); ivNumD.setOnClickListener(new OnClickListenerImpl()); tvCheck = (TextView) findViewById(R.id.tvCheck); etCheck = (EditText) findViewById(R.id.etCheck); setNum(); } private void setNum() { initNum(); tvHideA.setText("" + numArray[0]); tvHideA.setTextColor(randomColor()); tvHideB.setText("" + numArray[1]); tvHideB.setTextColor(randomColor()); tvHideC.setText("" + numArray[2]); tvHideC.setTextColor(randomColor()); tvHideD.setText("" + numArray[3]); tvHideD.setTextColor(randomColor()); Matrix matrixA = new Matrix(); //重設(shè)矩陣 matrixA.reset(); matrixA.setRotate(randomAngle()); Bitmap bmNumA = Bitmap.createBitmap(getBitmapFromView(tvHideA,20,50),0,0,20,50,matrixA,true); ivNumA.setImageBitmap(bmNumA); Matrix matrixB = new Matrix(); //重設(shè)矩陣 matrixB.reset(); matrixB.setRotate(randomAngle()); Bitmap bmNumB = Bitmap.createBitmap(getBitmapFromView(tvHideB,20,50),0,0,20,50,matrixB,true); ivNumB.setImageBitmap(bmNumB); Matrix matrixC = new Matrix(); //重設(shè)矩陣 matrixC.reset(); matrixC.setRotate(randomAngle()); Bitmap bmNumC = Bitmap.createBitmap(getBitmapFromView(tvHideC,20,50),0,0,20,50,matrixC,true); ivNumC.setImageBitmap(bmNumC); Matrix matrixD = new Matrix(); //重設(shè)矩陣 matrixD.reset(); matrixD.setRotate(randomAngle()); Bitmap bmNumD = Bitmap.createBitmap(getBitmapFromView(tvHideD,20,50),0,0,20,50,matrixD,true); ivNumD.setImageBitmap(bmNumD); } private Bitmap getBitmapFromView(View v,int width,int height ) { int widSpec = View.MeasureSpec.makeMeasureSpec(width,View.MeasureSpec.EXACTLY); int heiSpec = View.MeasureSpec.makeMeasureSpec(height,View.MeasureSpec.EXACTLY); //重新繪制圖片大小 v.measure(widSpec, heiSpec); // v.layout(0, 0, width, height); Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); //畫出圖片 Canvas canvas = new Canvas(bitmap); v.draw(canvas); return bitmap; } //設(shè)置隨機(jī)傾斜的角度 private int randomAngle() { return 20*(new Random().nextInt(5)-new Random().nextInt(3)); } //隨機(jī)生成顏色 private int randomColor() { colorArray[0]=0xFF000000; //BLACK colorArray[1] = 0xFFFF00FF; // MAGENTA colorArray[2] = 0xFFFF0000; // RED colorArray[3] = 0xFF00FF00; // GREEN colorArray[4] = 0xFF0000FF; // BLUE colorArray[5] = 0xFF00FFFF; // CYAN int randomColoId = new Random().nextInt(5); return colorArray[randomColoId]; } //初始化驗(yàn)證碼 private void initNum() { numStr=""; numStrTmp=""; for (int i = 0; i < numArray.length; i++) { //隨機(jī)生成10以內(nèi)數(shù)字 int numIntTmp = new Random().nextInt(10); //保存各個(gè)驗(yàn)證碼 numStrTmp = String.valueOf(numIntTmp); //保存整個(gè)驗(yàn)證碼 numStr = numStr+numStrTmp; numArray[i] = numIntTmp; } } private class OnClickListenerImpl implements View.OnClickListener { @Override public void onClick(View v) { //當(dāng)點(diǎn)擊的為登錄按鈕時(shí) if(v==btLogin){ //判斷賬戶字符是否為空, if (TextUtils.isEmpty(userEditText.getText().toString())){ //為空時(shí)抖動(dòng)提示 userEditText.setShakeAnimation(); Toast.makeText(MainActivity.this,"賬戶或密碼不能為空",Toast.LENGTH_SHORT).show(); } //判斷密碼字符是否為空 if (TextUtils.isEmpty(psdEditText.getText().toString())){ //為空時(shí)抖動(dòng)提示 psdEditText.setShakeAnimation(); Toast.makeText(MainActivity.this,"賬戶或密碼不能為空",Toast.LENGTH_SHORT).show(); } //驗(yàn)證輸入的驗(yàn)證碼是否正確 if(etCheck.getText().toString()!=null&&etCheck.getText().toString().trim().length()>0){ tvCheck.setVisibility(View.VISIBLE); if (numStr.equals(etCheck.getText().toString())){ tvCheck.setTextColor(Color.GREEN); tvCheck.setText("驗(yàn)證碼正確!"); }else{ tvCheck.setTextColor(Color.RED); tvCheck.setText("驗(yàn)證碼錯(cuò)誤!"); etCheck.setText(""); setNum(); } } //如果OnClick不是登錄按鈕時(shí)只剩下驗(yàn)證碼圖片有監(jiān)聽事件。等同于點(diǎn)擊驗(yàn)證碼圖片。改變驗(yàn)證碼。 }else { setNum(); tvCheck.setVisibility(View.GONE); } } } }
需要注意的知識(shí):
1.Bitmap.createBitmap(getBitmapFromView(tvHideA,20,50),0,0,20,50,matrixA,true);
Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)
Bitmap source:要從中截圖的原始位圖
int x: 起始x坐標(biāo)
int y:起始y坐標(biāo)
int width: 要截的圖的寬度
int height:要截的圖的高度
boolean filter 當(dāng)進(jìn)行的不只是平移變換時(shí),filter參數(shù)為true可以進(jìn)行濾波處理,有助于改善新圖像質(zhì)量;flase時(shí),計(jì)算機(jī)不做過濾處理。
2.intwidSpec = View.MeasureSpec.makeMeasureSpec(width,View.MeasureSpec.EXACTLY);
int heiSpec = View.MeasureSpec.makeMeasureSpec(height,View.MeasureSpec.EXACTLY);
設(shè)置View的寬和高。View.MeasureSpec.EXACTLY 指的是設(shè)置為實(shí)際View的大小。即前面的width(height)為多大就為多大。
3.Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); create一個(gè)圖標(biāo)。
4.Canvas canvas =newCanvas(bitmap);
v.draw(canvas); 畫出圖片
5.v.measure(widSpec, heiSpec);
//v.layout(0,0, width, height); 重新繪制圖片的大小。
后面是運(yùn)行時(shí)的圖片:
當(dāng)有輸入時(shí)右邊的一鍵刪除圖標(biāo)顯示、當(dāng)失去焦點(diǎn)時(shí)一鍵刪除圖標(biāo)隱藏、點(diǎn)擊驗(yàn)證碼更新驗(yàn)證碼:
后面的就不詳細(xì)圖示了。
源碼下載:http://xiazai.jb51.net/201610/yuanma/Androidlogin(jb51.net).rar
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android?Studio實(shí)現(xiàn)登錄界面功能
- Android實(shí)現(xiàn)登錄界面的注冊(cè)功能
- Android登錄界面的實(shí)現(xiàn)代碼分享
- Android實(shí)現(xiàn)注冊(cè)登錄界面的實(shí)例代碼
- Android設(shè)計(jì)登錄界面、找回密碼、注冊(cè)功能
- Android實(shí)現(xiàn)簡(jiǎn)潔的APP登錄界面
- Android屬性動(dòng)畫實(shí)現(xiàn)炫酷的登錄界面
- Android開發(fā)實(shí)例之登錄界面的實(shí)現(xiàn)
- Android QQ登錄界面繪制代碼
- Android Studio實(shí)現(xiàn)簡(jiǎn)易登錄界面制作
相關(guān)文章
Android開發(fā)-之監(jiān)聽button點(diǎn)擊事件的多種方法
本篇文章主要是介紹了Android開發(fā)之監(jiān)聽button點(diǎn)擊事件的方法,Android開發(fā)-之監(jiān)聽button點(diǎn)擊事件的方法總結(jié),有興趣的可以了解一下。2016-11-11Flutter Flar動(dòng)畫使用實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了Flutter Flar動(dòng)畫使用實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Android 中ScrollView嵌套GridView,ListView的實(shí)例
這篇文章主要介紹了Android 中ScrollView嵌套GridView,ListView的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03Android實(shí)現(xiàn)帶指示器的自動(dòng)輪播式ViewPager
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶指示器的自動(dòng)輪播式ViewPager的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Kotlin面向?qū)ο笾R(shí)點(diǎn)講解
面向?qū)ο缶幊掏ㄟ^對(duì)事物的抽象,大大的簡(jiǎn)化了程序的開發(fā)難度。我們常用的編程語言:Java、C++、Python都屬于面向?qū)ο缶幊?。Kotlin與java類似,也是一種面向?qū)ο缶幊陶Z言。本文從面向?qū)ο笕齻€(gè)基本特征:封裝、繼承、多態(tài),來闡述一下Kotlin中的面向?qū)ο缶幊?/div> 2022-12-12詳解Flutter?響應(yīng)式狀態(tài)管理框架GetX
這篇文章主要為大家介紹了Flutter?響應(yīng)式狀態(tài)管理框架GetX詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android RecyclerView詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Android RecyclerView詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-01-01Android中ScrollView監(jiān)聽滑動(dòng)距離案例講解
這篇文章主要介紹了Android中ScrollView監(jiān)聽滑動(dòng)距離案例講解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08最新評(píng)論