Android developer tutorial 1: implement a logon dialog box

Source: Internet
Author: User
Tags bmp image

Turn: http://hi.baidu.com/android_fans/blog/item/1e203ad8878d182b10df9b3c.html

 

Difficulty:
Suitable for: Android Developers

Brief description: for network applications, the "logon box" is quite common. There are no complicated items in the Code. It is basically a uidesign. It is suitable for practitioners and can be downloaded after the code is logged on.

Requirement Analysis:
1. Enter the user name and password
2. Extract user name and password information
3. Progress bar during logon
4. Timeout Processing
5. logon successful jump
6. (not all of them are listed. Please add them as needed)

Step 1:
Objective: To design the UI

1.1 compile layout XML login_view.xml

Tablelayout is a natural fit for the four-way regular layout. It is worth noting that each row is identified by a tablerow label. It's too ugly to post code on the Forum, so I only paste the key. After the complete code tutorial is completed, download is provided.

 

<Tablerow>

<Textview Android: text = "@ string/username"

Android: layout_width = "wrap_content"

Android: layout_height = "wrap_content"/>

<Edittext Android: layout_width = "fill_parent"

Android: layout_height = "wrap_content"
Android: layout_weight = "1.0"/>

</Tablerow>

The layout_weight attribute is added to extend edittext to the rightmost.

 

<Linearlayout>

<Button Android: text = "@ string/login"

Android: layout_width = "wrap_content"

Android: layout_height = "wrap_content"

Android: layout_weight = "1.0"/>

<Button Android: text = "@ string/cancel"

Android: layout_width = "wrap_content"

Android: layout_height = "wrap_content"

Android: layout_weight = "1.0"/>

</Linearlayout>

Here, the layout_weight attribute is used to ensure that the two buttons have equal width and can be filled with a line. Because 1.0: 1.0 =. The width is equal.

 

Let's look at the effect in eclipse.
[Attach] 501 [/Attach]

The effect looks pretty good.

1.2 write a class to test it

Both diyout and activity can load this layout.

Testloginview. Java

Package org. androidin. Tutorial;

Import Android. App. activity;
Import Android. App. Dialog;
Import Android. content. intent;
Import Android. OS. Bundle;
Import Android. View. view;
Import Android. View. View. onclicklistener;
Import Android. widget. Button;

Public class testloginview extends activity {
/** Called when the activity is first created .*/
Public static button btnactivity;
Public static button btndialog;
Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Setcontentview (R. layout. Main );

Btnactivity = (button) findviewbyid (R. Id. test_activity );
Btnactivity. setonclicklistener (New btnactivityoncliklistener ());

Btndialog = (button) findviewbyid (R. Id. test_dialog );
Btndialog. setonclicklistener (New btndialogonclicklistener ());
}

Private class btndialogonclicklistener implements onclicklistener {

Public void onclick (view v ){
Dialog dialog = new dialog (testloginview. This );
Dialog. setcontentview (R. layout. login_view );
Dialog. settitle (getstring (R. String. Address ));
Dialog. Show ();
}
}

Private class btnactivityoncliklistener implements onclicklistener {

Public void onclick (view v ){
Intent intent = new intent ();
Intent. setclass (testloginview. This, loginviewonactivity. Class );
Startactivity (intent );
}
}
}

Loginviewonactivity. Java

Package org. androidin. Tutorial;
Import Android. App. activity;
Import Android. OS. Bundle;

Public class loginviewonactivity extends activity {
Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Settitle (getstring (R. String. Address ));
Setcontentview (R. layout. login_view );
}
}

Device1.png (7.76 KB)

Device2.png (10.39 KB)

Create a BMP image. jpg (16.9 KB)


Step 2:
Add the progress UI to the target and design the login control architecture (LOGIN logic, failed or successfully handled ).

First, add progress. By default, progress is invisible. Therefore, set "gone" on the property of Android: visibility. This parameter will make the control not displayed and not placeholder, for more information, see the official documentation.

<Linearlayout Android: Id = "@ + ID/login_view_progress"
Android: visibility = "gone">
<Rogressbar Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
/>
<Textview Android: text = "@ string/is_logining"
Android: textsize = "17.5sp"
Android: layout_width = "wrap_content"
Android: layout_height = "fill_parent"
Android: gravity = "center"
/>
</Linearlayout> the next step is the key part. The login logic of each application is different, so write an Interface

Public interface onloginlistener {
Public Boolean onlogin (view V, string username, string password );
// View V is the view that calls this method, and their parameters are not mentioned.
Public void onloginsuccess (view V );
Public void onloginfailed (view V );
}

Next we need to encapsulate the entire loginview, because we need to add the view in XML to loginview, So we inherit the framelayout

Public class loginview extends framelayout {
Protected button btnlogin;
Protected button btncancel;
Protected edittext edtusername;
Protected edittext edtpassword;

Protected view progress;
Private onloginlistener;
Loginview (context); // initialize attributes

Public void setonloginlistener (onloginlistener L); // set the logon logic listener
Public void setcancelonclicklistener (onclicklistener L); // set the listening of the cancel button
Public void setloginonclicklistener (onclicklistener L); // set the listener for the login button
}

 

Next we will implement the method one by one.

 

Only one constructor method is reloaded here. In fact, multiple constructor methods may need to be reloaded. Therefore, write a function to initialize the view separately.

 

Private void initviews (){
Inflate (getcontext (), R. layout. login_view, this );
Btnlogin = (button) findviewbyid (R. Id. login_view_login );
Btncancel = (button) findviewbyid (R. Id. login_view_cancel );
Edtusername = (edittext) findviewbyid (R. Id. login_view_username );
Edtpassword = (edittext) findviewbyid (R. Id. login_view_password );
Btnlogin. setonclicklistener (New loginbuttonlistener (); // The default processing logic listener is described below.

Progress = findviewbyid (R. Id. login_view_progress );

}
Public loginview (context ){
Super (context );
Initviews ();
}
Public void setonloginlistener (onloginlistener L ){
Onloginlistener = L;
}
Public void setcancelonclicklistener (onclicklistener L ){
Btncancel. setonclicklistener (L );
}
Public void setloginonclicklistener (onclicklistener L ){
Btnlogin. setonclicklistener (L );
}

Let's look back at the default processing logic added above.

 

Private class loginbuttonlistener implements onclicklistener

 

For general applications, you must connect to the local database remotely through socket. Reading local data is fine, but it may take some time to use socket communication. In the event of network congestion, the login process is even longer. Second, socket is a blocking method, that is, if the connection is not applied, the thread that calls the socket is also in the waiting state. The program will not run.

 

So the solution is to create a thread to handle the login process.

 

 

Private class loginbuttonlistener implements onclicklistener {
Public void onclick (view v ){
If (onloginlistener! = NULL ){
Loginthread = new loginthread ();
Loginthread. Start ();
}
}
}

 

Protected class loginthread extends thread {
Public void run (){
Handler. sendemptymessage (set_onlogin_true); // you can specify that the control is unavailable.
Boolean flag = onloginlistener. onlogin (
Loginview. This,
Edtusername. gettext (). tostring (),
Edtpassword. gettext (). tostring ());

 

If (FLAG)
Onloginlistener. onloginsuccess (loginview. This );
Else
Onloginlistener. onloginfailed (loginview. This );

Handler. sendemptymessage (set_onlogin_false); // sets whether the control is available.
}
};

 

The handler here is used to change the control attributes in a non-main program thread. Android requires that the control attributes cannot be changed in other non-main threads. However, handler can be used to handle similar situations. For more information, see the official documentation.

 

This is the basic framework. Next we will explain how to use this loginview.

 

Of course, you must first implement an onloginlistener

 

Package org. androidin. Tutorial. view;

 

Import org. androidin. Tutorial. loginsuccessactivity;
Import org. androidin. Tutorial. R;

 

Import Android. content. context;
Import Android. content. intent;
Import Android. OS. Handler;
Import Android. View. view;
Import Android. widget. Toast;

 

Public class onloginlistenerimpl implements onloginlistener {

Protected object session; // It is used to save the return values of some logon statuses. It can be hashmap.

Protected handler; // all these methods are called in another thread, so handler is used to change the properties of some controls.

Public onloginlistenerimpl (handler ){
This. Handler = handler;
}

 

Public Boolean onlogin (view V, string username, string password ){
For (INT I = 0; I <10000000; I ++) // This method is used to simulate the blocked socket
;
If (username. Equals ("androidin") return true; // login successful
Return false; // Logon Failed
}

 

Public void onloginfailed (final view v ){
Handler. Post (New runnable () {// a toast is displayed when a failure occurs.
Public void run (){
Toast. maketext (
V. getcontext (),
V. getcontext (). gettext (R. String. login_failed ),
Toast. length_long). Show ();
}
});
}

 

Public void onloginsuccess (view v ){
Context context = V. getcontext ();
Context. startactivity (new intent (context,
Loginsuccessactivity. Class); // jump to the success page
}
}

 

Let's assemble it now. This example shows the control in activity.

Package org. androidin. Tutorial;

 

Import org. androidin. Tutorial. View. loginview;
Import org. androidin. Tutorial. View. onloginlistenerimpl;

 

Import Android. App. activity;
Import Android. OS. Bundle;
Import Android. OS. Handler;
Import Android. View. view;
Import Android. View. View. onclicklistener;

 

Public class loginviewonactivity extends activity {

Private loginview logv;

 

Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Settitle (getstring (R. String. Address ));
Logv = new loginview (this );
Logv. setonloginlistener (New onloginlistenerimpl (new handler ()));
Logv. setcancelonclicklistener (New onclicklistener (){
Public void onclick (view v ){
Finish ();
}
});
Setcontentview (logv );
}
}
So, easy !!

 

Device3.png (9.82 KB)

 

 

There is also a small bug. I don't know if you have found it. The bug fix remains in step 3.
Step 3:

Objective: To fix bugs and add timeout Processing

There is a small bug left in step 2. When you click the login button, if you force terminate (for example, press the back key) before the logon status returns ). The login logic cannot be terminated because the login logic is in a new thread. Therefore, you must be able to terminate the login logic thread. To terminate a thread, you can call thread. Stop () thread. Interrupt (). The stop method is not safe and may cause deadlocks. Interrupt only changes the thread state, rather than terminating the thread in real time.

Therefore, we set an islogincanceled to verify the status after the logon status is returned. If it is canceled, the following program will not be implemented.

Protected class loginthread extends thread {
Public void run (){
Handler. sendemptymessage (set_onlogin_true );
Boolean flag = onloginlistener. onlogin (loginview. This, edtusername
. Gettext (). tostring (), edtpassword. gettext (). tostring ());
If (islogincanceled ){
Return;
}
If (FLAG)
Handler. sendemptymessage (login_success );
Else
Handler. sendemptymessage (login_failed );
Handler. sendemptymessage (set_onlogin_false );
}
};

We adopt a similar method for timeout processing. After timeout, assign islogincanceled to true. The following logic will not be executed.
Private class loginbuttonlistener implements onclicklistener {
Public void onclick (view v ){
If (onloginlistener! = NULL ){
Islogincanceled = false;
If (timeout! = 0)
Handler. sendemptymessagedelayed (login_timeout, timeout );
Loginthread = new loginthread ();
Loginthread. Start ();
}
}
}

Private handler = new handler (){
@ Override
Public void handlemessage (Message MSG ){
Switch (msg. What ){
Case set_onlogin_true:
Setonloging (true );
Break;
Case set_onlogin_false:
Setonloging (false );
Break;
Case login_timeout:
Onloginlistener. onlogintimeout (loginview. This );
Logincancel ();
Sendemptymessage (set_onlogin_false );
Break;
Case login_success:
Onloginlistener. onloginsuccess (loginview. This );
Break;
Case login_failed:
Onloginlistener. onloginfailed (loginview. This );
Break;
}
Super. handlemessage (MSG );
}
};

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.