How to Create Text Stickers in Android?
Last Updated :
23 Feb, 2021
Not only a picture is worth a thousand words but also, they are cooler than monotonous text. In this article, we will learn how to create stickers from the TextView. This will be helpful if you are creating an app in which you want to add some text overlay functionality, for example, an image editing app. Also, we can see a very good implementation of this in the Hike App.
Image Source: Hike Android AppHow Does it Work?
The main concept we are using here is that we are converting the TextView into Bitmap and saving that bitmap in the phone storage. Now, we can do “n” number of manipulations in that TextView, like we can change the color, font, size, style, the appearance of the, etc of the TextView. Any changes we make in the TextView reflect in the sticker(bitmap) formed. Keeping this idea in mind, let’s begin creating the App. Note that we are going to implement this project using the Java language.
Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Adding a dependency to the build.gradle file
We will be using a library for picking up the color at runtime and changing the color of TextView accordingly. So add this dependency in build.gradle file.
implementation 'petrov.kristiyan:colorpicker-library:1.1.10'
Step 3: Adding font files
To make our sticker more beautiful we will add some font to the TextView. To do so we will require the font files in .ttf or .otf format. You can download any font file you like from the internet. Now once you have downloaded the files, go to the app > res > right-click > New > Folder > Font Folder and create a new Android Resources folder of the font in android studio and place the font files in that folder.
We will be using six font files for example and you can download these files from here.
Step 4: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file.
XML
<?xml version="1.0" encoding="utf-8"?>
<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:background="#0F9D58"
tools:context=".MainActivity">
<ImageButton
android:id="@+id/changeFont"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:background="#43A047"
android:src="@drawable/ic_android_black_24dp" />
<ImageButton
android:id="@+id/changeColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:background="#43A047"
android:src="@drawable/ic_android_black_24dp" />
<Button
android:id="@+id/convert"
style="@style/TextAppearance.AppCompat.Widget.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#7CB342"
android:text="Stickerize!"
android:textStyle="bold" />
<TextView
android:id="@+id/stickerTextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Geeks for Geeks"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@color/white"
android:textStyle="bold" />
<EditText
android:id="@+id/stickerEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:hint="Enter your text here.."
android:textAlignment="center" />
</RelativeLayout>
Step 5: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.res.ResourcesCompat;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import petrov.kristiyan.colorpicker.ColorPicker;
public class MainActivity extends AppCompatActivity {
TextView textSticker;
EditText editTextSticker;
ImageButton fontchange;
ImageButton colorPickerText;
Button createSticker;
// this will work as a counter to
// change the font of TextView
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textSticker = (TextView) findViewById(R.id.stickerTextview);
editTextSticker = (EditText) findViewById(R.id.stickerEditText);
colorPickerText = (ImageButton) findViewById(R.id.changeColor);
fontchange = (ImageButton) findViewById(R.id.changeFont);
createSticker = (Button) findViewById(R.id.convert);
createSticker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
executeSticker();
} catch (IOException e) {
e.printStackTrace();
}
}
});
// Here we have added a TextWatcher. The onTextChanged() method will change
// the text in TextVie as we type, in the EditText. This makes app more interactive.
editTextSticker.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
textSticker.setText(charSequence);
}
@Override
public void afterTextChanged(Editable editable) {
}
});
// Here we have implemented a small logic which changes the font of the TextView
// Whenever we click this button. The counter increments by one and reset to zero
// when it reaches value 6.
fontchange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (i) {
case 0:
i = 1;
// This is a very important method of this example.
// The setTypeFace() method sets the font of the TextView at runtime.
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.summer));
break;
case 1:
i = 2;
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.angel));
break;
case 2:
i = 3;
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.cute));
break;
case 3:
i = 4;
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.mandala));
break;
case 4:
i = 5;
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.painter));
break;
case 5:
i = 6;
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.newfont));
break;
case 6:
i = 0;
textSticker.setTypeface(ResourcesCompat.getFont(MainActivity.this, R.font.orange));
break;
}
}
});
colorPickerText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// create an instance of ColorPicker and invoke the ColorPicker dialog onClick.
final ColorPicker colorPicker = new ColorPicker(MainActivity.this);
colorPicker.setOnFastChooseColorListener(new ColorPicker.OnFastChooseColorListener() {
@Override
public void setOnFastChooseColorListener(int position, int color) {
// get the integer value of color selected from the dialog box and
// the color of the TextView.
textSticker.setTextColor(color);
}
@Override
public void onCancel() {
colorPicker.dismissDialog();
}
})
// set the number of color columns
// you want to show in dialog.
.setColumns(5)
// set a default color selected in the dialog
.setDefaultColorButton(Color.parseColor("#000000"))
.show();
}
});
}
// This method creates a Bitmap from the TextView
// and saves that into the storage
private void executeSticker() throws IOException {
// Create an OutputStream to write the file in storage
OutputStream imageOutStream;
// Although the ProgressDialog is not necessary but there may be cases when
// it might takes 2-3seconds in creating the bitmap.(This happens only when there is a
// large chunk of cache and also when app is running multiple threads)
final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Please wait..");
progressDialog.show();
// All the three methods are discussed later in this article.
// destroyDrawingCache(),buildDrawingCache(),getDrawingCache().
textSticker.destroyDrawingCache();
textSticker.buildDrawingCache();
Bitmap textStickerBitmap = textSticker.getDrawingCache();
// From Android 10 onwards using the former method gives error, because
// there is a security/privacy update in Android Q which doesn't allow
// access to third party files.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// In order to create a new image file in
// storage we do the following steps.
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "gfg.png");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
imageOutStream = getContentResolver().openOutputStream(uri);
// this method writes the file in storage. And finally
// our sticker has been created and
// successfully saved in our storage
textStickerBitmap.compress(Bitmap.CompressFormat.PNG, 100, imageOutStream);
// close the output stream after use.
imageOutStream.close();
progressDialog.dismiss();
// Now, incase you want to use that bitmap(sticker)
// at the very moment it is created
// we do the following steps.
// Open a Inputstream to get the data from file
final InputStream imageStream;
try {
// use the same uri which we previously used
// in writing the file, as it contains
// the path to that file.
imageStream = getContentResolver().openInputStream(uri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
// create a drawable from bitmap.
Drawable drawable = new BitmapDrawable(getResources(), selectedImage);
// You can do anything with this drawable.
// This drawable contains sticker png.
} catch (FileNotFoundException e) {
Toast.makeText(MainActivity.this, "File not found!!", Toast.LENGTH_SHORT).show();
}
// The else condition is executed if the device
// Android version is less than Android 10
} else {
String imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File image = new File(imagesDir, "gfg.jpg");
imageOutStream = new FileOutputStream(image);
textStickerBitmap.compress(Bitmap.CompressFormat.PNG, 100, imageOutStream);
imageOutStream.close();
final Uri imageUri = Uri.fromFile(image);
final InputStream imageStream;
try {
imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
Drawable drawable = new BitmapDrawable(getResources(), selectedImage);
// You can do anything with this drawable.
// This drawable contains sticker png.
} catch (FileNotFoundException e) {
Toast.makeText(MainActivity.this, "File not found!!", Toast.LENGTH_SHORT).show();
}
}
// Finally, print a success message.
Toast.makeText(this, "Sticker created successfully!!", Toast.LENGTH_SHORT).show();
}
}
Output: Run on Physical Device
Note about auto-scaling in compatibility mode: When auto-scaling is not enabled, this method will create a bitmap of the same size as this view. You should avoid calling this method when hardware acceleration is enabled. If you do not need the drawing cache bitmap, calling this method will increase memory usage and cause the view to be rendered in software once, thus negatively impacting performance.
Important Methods used in this Example
- buildDrawingCache: Forces the drawing cache to be built if the drawing cache is invalid.
- destroyDrawingCache: Frees the resources used by the drawing cache. If you call buildDrawingCache() manually without calling setDrawingCacheEnabled(true), you should clean up the cache with this method afterward.
- getDrawingCache: Returns the bitmap in which this view drawing is cached. The returned bitmap is null when caching is disabled. If caching is enabled and the cache is not ready, this method will create it. There is an overloaded function of this with a boolean parameter which indicates whether the generated bitmap should be scaled based on the current density of the screen when the application is in compatibility mode. The zero parameter method works the same as getDrawingCache(false).
- setDrawingCacheEnabled: Enables or disables the drawing cache. When the drawing cache is enabled, the next call to getDrawingCache() or buildDrawingCache() will draw the viewer in a bitmap.
Future Scope
- You can add the functionality of increasing or decreasing the TextView size at runtime.
- You can add a canvas to your app, this will allow dragging, stretching, rotating the TextView which would be more interactive.
- You can also try to implement this in a Chat App, where the user can generate a sticker from the text typed.
- Try typing in different languages and create the sticker.
Notes:
1. We don't require read write permissions here because the stickers or the bitmaps which we are saving in phone storage are owned by our own app.
2. From Android 10, method for accessing files from device storage has been changed. If you use earlier methods you might get absurd results.
3. If you call buildDrawingCache() manually without calling setDrawingCacheEnabled(true), you should cleanup the cache by calling destroyDrawingCache() afterwards.
Similar Reads
How to Create Marquee Text in Android?
In this article, we are going to create Marquee Text in Android Studio. Marquee is a scrolling piece of text that is displayed either horizontally or vertically. It is used to show some important notices or headlines. It makes the app UI much more attractive. Note that we are going to use Java as th
3 min read
How to Change Spinner Text Style in Android?
A Spinner in Android is a UI element used to display the list of items in a drop-down menu. The spinner is depicted as a downward arrow on the layout. Each of these items is selectable and can be used as user input. In this article, we will show you how to change the Spinner item text styles in Andr
3 min read
How to Convert Text to Speech in Android?
Text to Speech App converts the text written on the screen to speech like you have written "Hello World" on the screen and when you press the button it will speak "Hello World". Text-to-speech is commonly used as an accessibility feature to help people who have trouble reading on-screen text, but it
3 min read
How to Convert Speech to Text in Android?
In this article, speech to text feature is implemented in an application in Android. Speech to text means that anything that the user says is converted into text. This feature has come out to be a very common and useful feature for the users. In various places where search feature is implemented lik
5 min read
How to Read a Text File in Android?
A text file is a type of file that can store a sequence of characters or text. These characters can be anything that is human-readable. Such kind of files does not have any formatting for the text like Bold, Italics, Underline, Font, Font Size, etc. A Text file in Android can be used for accessing o
3 min read
How to Create Balloon Toast Message in Android?
In this article, we are going to creating a balloon Toast. This Library is one of the popular features that is commonly used in most Android Apps. We can get to see this feature in most of the shopping and messaging apps. With the help of this feature, you can get a hint about what to do next in any
2 min read
Best Practices for Using Text in Android
Text is the most widely used element in Android apps. Text is used in the form of a TextView or an EditText. As a result, in order to improve our performance, we must make the greatest use of text. We'll explore some of the best practices for using text on Android in this article. Text DesignText Pe
6 min read
How to Create Blink Effect on TextView in Android?
In this article, we are going to implement a very important feature related to TextView. Here we are adding the blink text feature on a TextView. This feature can be used to show important announcements or notifications in an App. Even we can add this feature to show important links for the user. So
2 min read
How to Create Outlined Text in Android using Jetpack Compose?
In Android, we can customize various aspects of a Text for displaying them accordingly. We can change the font size, and font family as well as apply various functions like bold, italics, etc. However, it is not possible to display an outline font for the same text. In case, you are unaware of what
3 min read
How to Generate QR Code in Android?
QR codes are used in many apps to display data in machine-readable form. These codes are used to represent data in a secure manner that is readable only by machines and not by humans. We have seen many apps that provide QR codes and we can scan those QR codes with our mobile device. In this article,
4 min read