In this app, you are introduced to the Fragment class in Android. The Fragment class can be treated as a sub-activity or sub-interface. You can create many fragments as your want. Each user interface that is created by every fragment can be added, replaced, or removed from the main activity so that you have dynamic user interface in your app. To create a fragment, you need to extends the Fragment class and save it with java extension. In the Login app, we need to fragments. One fragment is called LoginFragment. This fragment is added to the main activity when the app first opens.
LoginFragment.java
package com.example.login;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class LoginFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_login, container, false);
}
}
On this sub-interface, there are one TextView, two EditText, and one Button views. These views are loaded from the xml file called fragment_login. The content of the fragment.login.xml file is shown below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:background="@drawable/back_style"
>
<TextView
android:id="@+id/txt_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/label"
android:textSize="20sp"
/>
<EditText
android:id="@+id/txt_user"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/user_hint"
android:inputType="text" />
<EditText
android:id="@+id/txt_pwd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/pwd_hint"
android:inputType="textPassword" />
<Button
style="@style/AppTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doLogin"
android:text="@string/bt_login" />
</LinearLayout>
The TextView view is used to display the text "Login" at the top of the login form. One EditText allows the user to input the user name and another EditText is to input the password. The Login button validates the input data. If the login is invalid, the app only shows a message "Invalid login". Otherwise, the second fragment or sub-interface is displayed a welcome message "Welcome! You have loginned successfully.". For this simple app, the user name and password that are used in the validation process are defined as string resources in the strings. xml file. The string resources that are used in this layout file are defined in the strings.xml file. This is the content of the strings.xml file.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Login</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="user_hint">Enter user name</string>
<string name="pwd_hint">Enter password</string>
<string name="bt_login">Login</string>
<string name="label">Login</string>
<string name="username">myusername</string>
<string name="password">mypassword123</string>
</resources>
The second fragment is used to display the welcome message as mentioned above. This sub-interface shows when the login is valid. The layout file for this fragment is shown below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="@drawable/back_style"
>
<TextView
android:id="@+id/txtsucess_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
/>
</LinearLayout>
The backround of each fragment is defined by a resource file called back_style.xml. This file is stored in the res/drawable directory. The content of this file is shown below.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:startColor="#ffffff"
android:endColor="#00ff00"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#171717" />
<corners
android:radius="4dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
The second fragment is defined in the java file called LogSucessFragment. To pass a value from the main activity to a fragment you need to define the constructor of the fragment class. This constructor is called newInstance. In this app, once the login is valid, the welcome message is passed from the main activity to the second fragment through this constructor. To refer to a view in the fragment, you need to user the getActivity method of the fragment class. This method returns the activity that passes data to the fragment. In this case it is the main activity. When you got the activity object, you can use its findViewById method to refer to any view within the fragment class.
LogSuccessFragment.java
package com.example.login;
import android.app.Activity;import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class LogSuccessFragment extends Fragment {
//@Override
//Activity mAct;
static String arg;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_success, container, false);
}
public static LogSuccessFragment newInstance(String str){
arg=str;
return(new LogSuccessFragment());
}
public void onStart(){
super.onStart();
TextView txtview = (TextView)getActivity().findViewById(R.id.txtsucess_view);
txtview.setText(arg);
}
}
The MainActivity.java file that acts as the main interface of the Login app is written as shown below. To support older Android versions (lower than 3.0) you need to use the FragmentActivity instead of Activity class. The FragmentActivity and all other fragments used in this app are in Support Library v4. If you got the latest Android SDK installed on your machine, you will have this library automatically in your project. In your project window, you can find this library by expanding or double-clicking the Android Private Libraries.
To add a fragment to the main activity. You need to create the instance of the fragment. Then use the add method of the Transaction object to to add the fragment instance to the main activity. You can get the Transaction object by using the beginTransaction method from the fragment manager. Replacing or removing a fragment also follows this process except you need to change from add to replace or remove method.
package com.example.login;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoginFragment lf=new LoginFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,lf).commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void doLogin(View view){
EditText txtuser=(EditText)findViewById(R.id.txt_user);
EditText txtpassword=(EditText)findViewById(R.id.txt_pwd);
String username=getResources().getString(R.string.username);
String password=getResources().getString(R.string.password);
if(txtuser.getText().toString().equals(username) && txtpassword.getText().toString().equals(password)){
String mess="Welcome! You have logined successfully.";
LogSuccessFragment logf=LogSuccessFragment.newInstance(mess);
FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
transact.replace(R.id.fragment_container, logf,"log");
transact.addToBackStack(null);
transact.commit();
}
else
Toast.makeText(this, "Invalid login", Toast.LENGTH_SHORT).show();
}
}
The layout file of the main activity simply contains a FragmentLayout container. This file is called activity_main.xml file.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Download apk file of the Login app