-
Notifications
You must be signed in to change notification settings - Fork 24
Android Chat Screen
Now that we have the Contact screen ready, it's only natural to continue with a Chat screen that we'll use to communicate with our contacts.
We'll start by creating a basic activity using the Android Studio's wizard. If we go to File > New > Activity > Basic Activity we'll be presented with a screen similar to the one below.
After we specify the name of the new activity, we can also specify something called a Hierarchical Parent. This will tell Android Studio to automatically provide the default implementation for the "Up" button for this activity. We are setting this value to our NavigationActivity
, which means that when a users presses the "Up" or "Back" button, he'll be taken to NavigationActivity
screen.
All that this feature really does is adding the below meta-data to the new activity in AndroidManifest.xml.
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.thesis.smukov.anative.NavigationActivity" />
As I usually do with everything I need to implement for the first time, I searched the web a little bit for existing ideas and solutions on how to create the Chat Activity in Android. After going through a few resources, I got really lucky by finding the following post created by JoCodes on CodeProject. His sample code gave me a great start for this activity, and he has provided everything you might need, even the NinePatch resources for the chat bubbles.
As this application continues to grow I'll certainly make a lot of changes to the code provided in the CodeProject's post that I mentioned, but for now, I'll use a lot of the code as is. Firstly, I added the two NinePatch
images (in_message_bg
and out_message_bg
) to my drawable folder. Then I added the ChatMessage.java
, and list_item_chat_message.xml
code without making any changes to them. To the ChatActivity
I made minimal changes, only changing the extended class from the deprecated ActionBarActivity
to the AppCompatActivity
, and changing the type of sendBtn
from Button
to ImageButton
, as I also changed the chat layout quite a bit. Below you can see the new version of the activity_chat.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<LinearLayout
android:id="@+id/chatControls"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<EditText
android:id="@+id/messageEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:hint="@string/typeMessage"
android:layout_weight="0.8"/>
<ImageButton
android:id="@+id/chatSendButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_menu_send"
android:background="@android:color/transparent"
android:layout_weight="0.2"/>
</LinearLayout>
<ListView
android:id="@+id/messagesContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="false"
android:layout_marginBottom="20dp"
android:layout_above="@+id/chatControls"
android:layout_marginTop="10dp"
android:listSelector="@android:color/transparent"
android:transcriptMode="alwaysScroll"
android:divider="@null" />
</RelativeLayout>
The key thing inside this new layout file is the grouping of EditText
and ImageButton
inside a single LinearLayout
parent, which allowed me to grow the height of my button as new lines of text are added to EditText
. I also used the android:layout_weight
attribute to set the EditText
to 80%, and the ImageButton
to 20% of the full layout width.
Finally, I made some minimal changes to the ChatAdapter
as I wanted my chat bubbles to be on the right, and my correspondent's on the left side. All the changes made were inside the setAlignment
method, where I swapped the two drawables for chat bubbles, and switched the Gravity
and RelativeLayout alignment.
I've used the term NinePatch
a few times in the section above. Let's explain what this really is by using the official Android documentation:
A NinePatchDrawable
graphic is a stretchable bitmap image, which Android will automatically resize to accommodate the contents of the View in which you have placed it as the background. An example use of a NinePatch
is the backgrounds used by standard Android buttons — buttons must stretch to accommodate strings of various lengths. A NinePatch
drawable is a standard PNG image that includes an extra 1-pixel-wide border. It must be saved with the extension .9.png, and saved into the res/drawable/ directory of your project.
The border is used to define the stretchable and static areas of the image. You indicate a stretchable section by drawing one (or more) 1-pixel-wide black line(s) in the left and top part of the border (the other border pixels should be fully transparent or white).
You can also define an optional drawable section of the image (effectively, the padding lines) by drawing a line on the right and bottom lines. If a View object sets the NinePatch as its background and then specifies the View's text, it will stretch itself so that all the text fits inside only the area designated by the right and bottom lines (if included). If the padding lines are not included, Android uses the left and top lines to define this drawable area.
Here is a sample NinePatch file used to define a button:
Now let's implement a way for our users to navigate to this Chat activity.
We implemented a BaseNavigationFragment
class that is a base class for all of our fragments that should appear inside the main NavigationActivity
. This BaseNavigationFragment
has an abstract method called prepareFloatingActionButton()
that all extending classes must implement. Inside this method we are changing the icon and the function of the FloatingActionButton
inside the NavigationActivity
, so that it matches the context of the displayed fragment. We are using this method to handle the navigation from Contact to Chat screen. Below you can see the implementation of this method for ContactFragment
class:
@Override
protected void prepareFloatingActionButton(){
if(fab == null){
fab = (FloatingActionButton) getActivity().findViewById(R.id.fab);
}
fab.show();
fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.ic_forum_black_24dp));
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), ChatActivity.class);
startActivity(intent);
}
});
}
To complete the Chat screen we will enable the Action Bar that was hidden by default by Android Studio when it generated the initial Activity classes. We will also set the title of the activity dynamically to the name of the contact that we are chatting with.
If we delete the following android:theme="@style/AppTheme.NoActionBar"
line from our ChatActivity
in AndroidManifest.xml the Action Bar will appear.
Now we just need to set the appropriate title for the ChatActivity
. For this we'll use the setTitle(..)
method that we'll add to onCreate(..)
inside the ChatActivity
class.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
setTitle("Dr. Gregory House");//hard-coded for now
initControls();
}
It took me less than 2 hours to implement all of this. I was very lucky that I found this great CodeProject post which got me started fast. However, that's the benefit of working on a pretty mature platform that is Android. There are lots of resources online, and you don't have to reinvent the wheel every time. We'll see how the Ionic2 Chat implementation will compare.
- https://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
- http://www.codeproject.com/Tips/897826/Designing-Android-Chat-Bubble-Chat-UI
Direct:
- https://github.com/smukov/AvI/commit/963428361aef82262728f116f294733a4761e38a
- https://github.com/smukov/AvI/commit/76da9279b1bb45729b7fe47f33581644d4281934
- https://github.com/smukov/AvI/commit/511024cd3b1a60bf04fb3361dbb0a3a59c9bb88c
- https://github.com/smukov/AvI/commit/aaaf3167f7d1b58c532a5dbec629eeeae0c60689
Related:
- Android
- Getting Started
- Project Structure
- Gradle
- Menu
- Theming
- Login Screen
- Menu & Navigation
- Importing Library From GitHub
- Creating Reusable Layouts
- Adding New Icons
- Profile Screen
- Chat Screen
- Contacts Screen
- Pending Invites Screen
- Settings Screen
- Add Library Dependency
- Discover Users Screen
- Splash Screen
- Auth0
- Authentication Logic
- Profile Screen Logic
- Send Feedback
- Authenticated to Firebase via Auth0
- Saving User Info to Firebase
- Storing User Connection Info to Firebase
- Calculating Distance Between Users
- Chat Logic
- Handling Device Rotation
- Android Other
- Ionic
- Getting Started
- Project Structure
- Menu
- Theming
- Login Screen
- Adding Images
- Creating Reusable Layouts
- Adding New Icons
- Profile Screen
- Contact Screen
- Elastic Textarea
- Chat Bubble
- Chat Screen
- Contacts Screen
- Pending Invites Screen
- Settings Screen
- Discover Users Screen
- Splash Screen
- Animations
- Auth0
- Storing User Data
- Profile Screen Logic
- Send Feedback
- Update to Ionic RC0
- Reimplemented Auth0 with Ionic RC0
- Authenticated to Firebase via Auth0
- Saving User Info to Firebase
- Storing User Connection Info to Firebase
- Calculating Distance Between Users
- Chat Logic
- Handling Device Rotation
- Ionic Other
- Version Updating
- Cordova
- Other
- Messaging