Fragments
Fragments in Android are reusable user interface (UI) components that can be used to build flexible and dynamic applications for a wide range of devices, including phones, tablets, and even wearables. Fragments allow you to build modular UIs, which can be combined or reused across multiple activities or layouts.
A fragment represents a behavior or a portion of UI in an activity, similar to a sub-activity, but is designed to be reusable across different activities. Fragments were introduced in Android 3.0 (Honeycomb), and since then, they have become an essential part of the Android framework.
Fragment Life Cycle
Img Ref - StudyTonight
Fragments can be used to build UIs that can adapt to different screen sizes and orientations, which is important for building responsive applications that can run on various devices.
In Android, fragments have their own lifecycle which can be broken down into six different states:
Unattached: In this state, the fragment is not yet associated with any activity. It is created, but not added to an activity.
Attached: In this state, the fragment is associated with an activity. It has been added to an activity, but it is not yet visible.
Created: In this state, the fragment has been created, and its views have been inflated. However, it is not yet visible.
Started: In this state, the fragment is visible to the user, but not yet in the foreground. This means that the fragment's onStart() method has been called.
Resumed: In this state, the fragment is in the foreground and actively interacting with the user. This means that the fragment's onResume() method has been called.
Paused: In this state, the fragment is still visible, but it is no longer in the foreground. This means that the fragment's onPause() method has been called.
Stopped: In this state, the fragment is no longer visible to the user. This means that the fragment's onStop() method has been called.
Destroyed: In this state, the fragment has been removed from the activity and its resources have been released. This means that the fragment's onDestroy() method has been called.
Note that the lifecycle of a fragment is closely tied to the lifecycle of the activity to which it is attached. Therefore, a fragment's lifecycle can be affected by the activity's lifecycle events, such as onStart() and onStop().
Basic Example
Here's a simple example of how to use a fragment in your application. Let's say you have an activity that displays a list of items, and when you click on an item, you want to display some details about that item.
First, create a new fragment class that will display the item details:
here's a basic complete example of fragments in Android:
MainActivity.java:
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements FragmentA.OnButtonClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Start with FragmentA
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment_container, new FragmentA());
ft.commit();
}
@Override
public void onButtonClick() {
// Replace FragmentA with FragmentB when button is clickedFragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, new FragmentB());
ft.addToBackStack(null);
ft.commit();
}
}
activity_main.xml:
<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" />
FragmentA.java:
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class FragmentA extends Fragment {
private OnButtonClickListener mListener;
public interface OnButtonClickListener {
void onButtonClick();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnButtonClickListener) {
mListener = (OnButtonClickListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnButtonClickListener");
}
}
@Override
public View onCreateView(
@NonNull
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
Button button = view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onButtonClick();
}
});
return view;
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
fragment_a.xml:
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me" />
FragmentB.java:
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentB extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
TextView textView = view.findViewById(R.id.textView);
textView.setText("Fragment B");
return view;
}
}
fragment_b.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
This example consists of two fragments: FragmentA and FragmentB. FragmentA has a button and FragmentB has a TextView. When the button in FragmentA is clicked, FragmentA is replaced with FragmentB, which displays the text "Fragment B" in the TextView
Output of the above code will look like this before and after click -
Advanced Examples
Fragments can be used for a wide range of UI tasks, from displaying simple lists to building complex multi-pane layouts. Here are a few advanced examples:
Multi-Pane Layouts
Fragments can be used to build multi-pane layouts that can adapt to different screen sizes and orientations. For example, you could create an activity that displays a list of items on the left-hand side of the screen, and when the user selects an item, it displays the details on the right-hand side of the screen.
Communication between Fragments
Often times, fragments need to communicate with each other. For example, when a user selects an item in one fragment, the details of that item should be displayed in another fragment. In such cases, you can use the activity as an intermediary between the two fragments.
The basic idea is that one fragment sends a message to the activity, and the activity passes that message on to the other fragment. Here's an example of how you can achieve this:
public class ListFragment extends Fragment {
private OnItemSelectedListener listener;
public interface OnItemSelectedListener {
void onItemSelected(Item item);
}
// ...
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnItemSelectedListener) {
listener = (OnItemSelectedListener) context;
} else {
throw new ClassCastException(context.toString() + " must implement ListFragment.OnItemSelectedListener");
}
}
private void itemClicked(Item item) {
listener.onItemSelected(item);
}
}
public class DetailsFragment extends Fragment {
private TextView detailsText;
public void updateDetails(Item item) {
detailsText.setText(item.getDetails());
}
}
public class MainActivity extends AppCompatActivity implements ListFragment.OnItemSelectedListener {
private DetailsFragment detailsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
detailsFragment = (DetailsFragment) getSupportFragmentManager().findFragmentById(R.id.details_fragment);
}
@Override
public void onItemSelected(Item item) {
detailsFragment.updateDetails(item);
}
}
In this example, the ListFragment defines an interface called OnItemSelectedListener which the activity must implement. The ListFragment then uses this interface to send messages to the activity.
The MainActivity implements the OnItemSelectedListener interface and passes itself as a listener to the ListFragment. When the user selects an item in the ListFragment, the onItemSelected method in the activity is called. The activity then updates the DetailsFragment with the details of the selected item.
Fragments are an important part of Android development. They allow you to create modular, reusable UI components that can be combined in different ways to create rich and dynamic user interfaces. By understanding the basics of fragments, you can build more powerful and flexible apps.
Intents/Filters
In Android development, intent and filters are essential concepts that allow apps to interact with each other and pass information between them.
Intents
An Intent is an abstract description of an operation to be performed. It is a messaging object that can be used to request an action from another app component, or to transfer data between app components.
Types of Intents
There are two types of intents in Android:
Img Ref - sanfoundary
Implicit Intents - Implicit intents are used to request an action from other apps without knowing which app will perform the action. For example, opening a web page or making a phone call. Implicit intents do not specify a component name but instead define an action to perform. For example:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"));
startActivity(intent);
In this example, we create an implicit Intent to open a web page using the default web browser. We specify the ACTION_VIEW action to indicate that we want to view something, and a Uri object that represents the URL of the web page we want to open.
Explicit Intents - Explicit intents are used to start a specific activity within an app component. Explicit intents specify the component name and the action to be performed. For example:
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
In this example, we create an explicit Intent to start the SecondActivity activity from the MainActivity activity.
Intent Filters
An Intent Filter is a declarative way to advertise a component’s ability to handle certain intents. It is used to specify the types of intents that an app component can respond to.
Intent filters are defined in the app’s AndroidManifest.xml file, and they specify the type of data the component can handle, the action the component can perform, and the category of the intent.
Example
Suppose you have an app that allows users to share a picture with another app. In this case, you can use an implicit intent to request an action from the other app. The following code snippet shows an example of an implicit intent:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, "Share image using"));
Here, the intent's action is set to ACTION_SEND, which is a common action used to share data. The intent also includes the image data to be shared, which is specified with EXTRA_STREAM and the MIME type of the data.
Here's a simple example of how to use intents to launch a second activity in an Android app:
Create a new Android Studio project with an Empty Activity.
In the app's MainActivity class, add a button to the layout and set an OnClickListener for the button. Inside the onClick method, create an Intent to launch the second activity:
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
Here, we create an Intent to launch the SecondActivity class, which we assume has already been created in the app.
In the app's SecondActivity class, add a layout and some text to display:
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView textView = findViewById(R.id.textView);
textView.setText("This is the second activity");
}
}
In this code, we create a new TextView object and set its text to "This is the second activity" using setText() method.
Run the app and click the button on the main activity. This should launch the second activity, which will display the text "This is the second activity".
Here is an Output of this code before and after click -
In this example, we used an explicit intent to launch the second activity by specifying its class name in the Intent constructor. The startActivity() method is used to launch the activity. When the second activity is launched, it displays the text specified in its layout file.
This is a basic example of how intents can be used in Android to launch a new activity. However, intents can be used for a wide range of purposes in Android, such as starting services, sending broadcast messages, and more.
Components of Intents
In Android, an Intent is a messaging object that is used to communicate between components of an app. An Intent can be used to start a new activity, service, or broadcast, or to pass data between components. Here are the components of an Intent object:
Action: The action of an Intent is a string that describes the type of operation to be performed. It indicates what the receiver of the Intent should do with it. Some common actions include ACTION_VIEW, which is used to display data, ACTION_SEND, which is used to send data, and ACTION_EDIT, which is used to edit data.
Data: The data of an Intent is a Uri object that specifies the data to be acted upon. The data can be a content Uri, a file Uri, or any other type of Uri that the receiver of the Intent can handle. For example, if you want to view a web page in a browser, you would create an Intent with the ACTION_VIEW action and a Uri object that represents the URL of the web page.
Type: The type of an Intent is a string that specifies the MIME type of the data to be acted upon. It indicates the format of the data and can be used by the receiver of the Intent to determine how to handle the data. For example, if you want to share an image file, you would create an Intent with the ACTION_SEND action and set the type to image/* to indicate that the data is an image file.
Category: The category of an Intent is a string that specifies additional information about the Intent. It can be used by the system to determine which components are eligible to handle the Intent. Some common categories include CATEGORY_LAUNCHER, which indicates that an activity is the main entry point for the app, and CATEGORY_BROWSABLE, which indicates that an activity can be launched from a web browser.
Extras: The extras of an Intent are a Bundle object that contains additional data to be passed between components. The extras can be used to pass any type of data, such as strings, integers, or custom objects.
By using these components, you can create powerful and flexible Intent objects that can be used to communicate between components of your app and with other apps.
Filters
Filters are used to specify the types of intents that an app component can respond to. In other words, a filter is used to define which intents an app component can handle.
Types of Filters
There are three types of filters in Android:
Action Filters - An action filter is used to specify the type of action an app component can handle. For example, an activity that can handle the ACTION_VIEW action can display web pages, images, and other types of data.
Category Filters - A category filter is used to specify the category of the intent an app component can handle. For example, an activity that can handle the CATEGORY_BROWSABLE category can be launched from a web browser.
Data Filters - A data filter is used to specify the type of dataan app component can handle. It specifies the data scheme, data type, and data path pattern that an app component can handle.
Example
Suppose you have an app that can handle intents for opening a particular file type. In this case, you can define a filter for the app component that specifies the MIME type of the file type. The following code snippet shows an example of a filter:
<activity android:name=".MyActivity"><intent-filter><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:mimeType="application/pdf" /></intent-filter></activity>
Here, the activity's intent filter specifies that it can handle the VIEW action and has two categories, DEFAULT and BROWSABLE. It also specifies that it can handle files with the MIME type application/pdf.
Overall, intents and filters are important concepts in Android development as they allow apps to communicate with each other and pass information between them. Understanding how to use them effectively can help you create more powerful and versatile Android apps.
We hope this blog has been helpful in understanding Fragments, Intents and Filters in Android. By using Intents and Filters, you can create more powerful and flexible Android apps that can communicate and interact with other apps on the device.
Thanks for reading, and happy coding!