I need implement group chat view like what's app.
Please find below example code which I am tried
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:paddingBottom="#dimen/size_05"
android:paddingTop="#dimen/size_05"
android:layout_marginRight="#dimen/size_80"
android:background="#drawable/chat_white_border"
android:orientation="vertical">
<TextView
android:id="#+id/txt_friends_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="false"
android:paddingLeft="#dimen/size_10"
android:paddingRight="#dimen/size_10"
android:text="name"
android:textColor="#color/chat_friends_name"
android:textSize="#dimen/size_12" />
<view
android:id="#+id/ll_c_friends_chat_message"
class="com.view.ChatBubbleLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="#+id/txt_friends_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:paddingLeft="#dimen/size_10"
android:paddingRight="#dimen/size_10"
android:text="name1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center|right"
android:orientation="horizontal">
<TextView
android:id="#+id/txt_rec_chat_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="#dimen/size_10"
android:text="11.00 PM"
android:textColor="#color/grey"
android:textSize="#dimen/size_10" />
</LinearLayout>
</view>
</LinearLayout>
</LinearLayout>
Custom view file:
package com.view;
import android.annotation.TargetApi;
import android.content.Context;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
/**
* Created by Priyan
*/
public class ChatBubbleLayout extends FrameLayout {
public ChatBubbleLayout(Context context) {
super(context);
}
public ChatBubbleLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChatBubbleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(21)
public ChatBubbleLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
TextView message_textView = (TextView) getChildAt(0);
View localView = getChildAt(1);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int view_size = View.MeasureSpec.getSize(widthMeasureSpec);
Layout messageTextviewLayout = message_textView.getLayout();
int linestart = messageTextviewLayout.getLineStart(messageTextviewLayout.getLineCount() - 1);
int lineend = messageTextviewLayout.getLineEnd(messageTextviewLayout.getLineCount() - 1);
int desiredWidth = (int) Layout.getDesiredWidth(message_textView.getText()
.subSequence(linestart, lineend), message_textView.getPaint());
int measuredWidth = message_textView.getMeasuredWidth();
int requiredWidth = Math.min(measuredWidth,
(int) Math.ceil(Layout.getDesiredWidth(message_textView.getText(),
message_textView.getPaint())) + message_textView.getPaddingRight() +
message_textView.getPaddingLeft());
if (view_size - getPaddingLeft() - getPaddingRight()
>= requiredWidth + localView.getMeasuredWidth()) {
setMeasuredDimension(requiredWidth + localView.getMeasuredWidth() +
getPaddingLeft() + getPaddingRight(), getMeasuredHeight());
} else if ((requiredWidth - message_textView.getPaddingLeft() - message_textView.getPaddingRight()
< desiredWidth + localView.getMeasuredWidth())) {
setMeasuredDimension(getMeasuredWidth(),
getMeasuredHeight() + localView.getMeasuredHeight());
}
}
}
I got result like:
You can see that time is not aligned properly to exteme right of the view on received message...
I need group chat view similar like what's app...
Related
Well
I m just learning custom viewgroups in android so i have made a simple viewgroup. i named it LearnLayout
i have custom layoutparam in it, called as LearnLayoutParams
Problem
when i use custom attributes on children. those attributes are not being parsed in LearnLayoutParams adn i get default values
Code
here are my code files
LearnLayout.java
this is the cusom viewgroup class file
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.RequiresApi;
import com.test.learnviewpagertransformations.MainActivity;
import com.test.learnviewpagertransformations.R;
public class LearnLayout extends ViewGroup {
private static final String TAG = MainActivity.TAG;
public LearnLayout(Context context) {
super(context);
}
public LearnLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LearnLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int maxWidth = 0;
int maxHeight = 0;
for(int i=0; i<getChildCount(); i++){
View childView = getChildAt(i);
if(childView.getVisibility() != GONE){
measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0);
final LearnLayoutParams lp = (LearnLayoutParams) childView.getLayoutParams();
int childWidth = lp.leftMargin + childView.getMeasuredWidth() + lp.rightMargin;
int childHeight = lp.topMargin + childView.getMeasuredHeight() + lp.bottomMargin;
maxWidth = Math.max(childWidth, maxWidth);
maxHeight = maxHeight + childHeight;
}
}
setMeasuredDimension(maxWidth, maxHeight);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int fromLeft = getPaddingLeft();
int fromTop = getPaddingTop();
int fromRight = right - left - getPaddingRight();
int fromBottom = bottom - top - getPaddingBottom();
for(int i=0; i<getChildCount(); i++){
View childView = getChildAt(i);
if (childView.getVisibility() != GONE) {
final LearnLayoutParams lp = (LearnLayoutParams) childView.getLayoutParams();
childView.layout(
fromLeft + lp.leftMargin,
fromTop + lp.topMargin,
fromRight - lp.rightMargin,
fromTop + lp.topMargin + lp.height
);
childView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Log.i(TAG, "onLayout: " + lp.backgroundColor);
}
});
childView.setBackgroundColor(getColor(lp.backgroundColor));
fromTop = fromTop + childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
}
}
}
#Override
public LearnLayoutParams generateLayoutParams(AttributeSet attrs) {
return new LearnLayoutParams(getContext(), attrs);
}
#Override
protected LearnLayoutParams generateDefaultLayoutParams() {
return new LearnLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
#Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LearnLayoutParams(p);
}
#Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LearnLayoutParams;
}
public static class LearnLayoutParams extends MarginLayoutParams {
public int backgroundColor = 0;
public LearnLayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray a = c.obtainStyledAttributes(R.styleable.LearnLayoutLP);
backgroundColor = a.getInt(R.styleable.LearnLayoutLP_layout_background_color, backgroundColor);
Log.i(TAG, "LayoutParams: " + backgroundColor);
a.recycle();
}
public LearnLayoutParams(int width, int height) {
super(width, height);
}
public LearnLayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
private int getColor(int backgroundColor){
switch (backgroundColor){
case 0:
return Color.RED;
case 1:
return Color.BLUE;
case 2:
return Color.GREEN;
default:
return Color.BLACK;
}
}
}
activity_learn_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.test.learnviewpagertransformations.views.LearnLayout
android:background="#99ff99"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<View
app:layout_background_color="red"
android:layout_margin="50dp"
android:layout_width="100dp"
android:layout_height="100dp" />
<LinearLayout
android:id="#+id/testView"
android:gravity="center"
app:layout_background_color="blue"
android:layout_margin="50dp"
android:layout_width="100dp"
android:layout_height="100dp">
<TextView
android:textStyle="bold"
android:textColor="#fff"
android:text="Test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<View
app:layout_background_color="green"
android:layout_margin="50dp"
android:layout_width="100dp"
android:layout_height="100dp" />
</com.test.learnviewpagertransformations.views.LearnLayout>
<!--<com.test.learnviewpagertransformations.views.CustomLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!– put first view to left. –>
<TextView
android:background="#drawable/filled_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_position="left"
android:layout_gravity="fill_vertical|center_horizontal"
android:text="l1"/>
<!– stack second view to left. –>
<TextView
android:background="#drawable/filled_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_position="left"
android:layout_gravity="fill_vertical|center_horizontal"
android:text="l2"/>
<!– also put a view on the right. –>
<TextView
android:background="#drawable/filled_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_position="right"
android:layout_gravity="fill_vertical|center_horizontal"
android:text="r1"/>
<!– by default views go in the middle; use fill vertical gravity –>
<TextView
android:background="#drawable/green"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical|center_horizontal"
android:text="fill-vert"/>
<!– by default views go in the middle; use fill horizontal gravity –>
<TextView
android:background="#drawable/green"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|fill_horizontal"
android:text="fill-horiz"/>
<!– by default views go in the middle; use top-left gravity –>
<TextView
android:background="#drawable/blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|left"
android:text="top-left"/>
<!– by default views go in the middle; use center gravity –>
<TextView
android:background="#drawable/blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="center"/>
<!– by default views go in the middle; use bottom-right –>
<TextView
android:background="#drawable/blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:text="bottom-right"/>
</com.test.learnviewpagertransformations.views.CustomLayout>-->
</LinearLayout>
attrs.xml
custom attributes that i have made for my layoutparams
<declare-styleable name="LearnLayoutLP">
<attr name="layout_background_color">
<enum name="red" value="0" />
<enum name="blue" value="1" />
<enum name="green" value="2" />
</attr>
</declare-styleable>
What i think
there is something i m missing in onLayout and onMeasure and because of that i m not getting the correct values of custom attributes. If you check my custom layoutparams class even at that place i dont get the values i have used all i get in logs is default value that it 0
Request
Please share whatever you have in your mind
I ll gladly welcome any amendments and improvements
_/\_
This question already has answers here:
Put constant text inside EditText which should be non-editable - Android
(18 answers)
Closed 6 years ago.
I want an EditText which displays a fixed text, something like display below.
try this one
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="IN +91"/>
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:inputType="textPersonName"
android:hint="Enter mobile number here"/>
</LinearLayout>
Refer this https://medium.com/#ali.muzaffar/adding-a-prefix-to-an-edittext-2a17a62c77e1#.y6uxyppam
public class PrefixEditText extends AppCompatEditText {
float mOriginalLeftPadding = -1;
public PrefixEditText(Context context) {
super(context);
}
public PrefixEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PrefixEditText(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
calculatePrefix();
}
private void calculatePrefix() {
if (mOriginalLeftPadding == -1) {
String prefix = (String) getTag();
float[] widths = new float[prefix.length()];
getPaint().getTextWidths(prefix, widths);
float textWidth = 0;
for (float w : widths) {
textWidth += w;
}
mOriginalLeftPadding = getCompoundPaddingLeft();
setPadding((int) (textWidth + mOriginalLeftPadding),
getPaddingRight(), getPaddingTop(),
getPaddingBottom());
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String prefix = (String) getTag();
canvas.drawText(prefix, mOriginalLeftPadding,
getLineBounds(0, null), getPaint());
}
}
Usage:
<com.alimuzaffar.customwidgets.PrefixEditText
fontPath="fonts/Lato-Light.ttf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textSize="24sp"
android:tag="+61 "
android:text="1234" />
OR
android-phone-number-with-flags
[https://github.com/dlukashev/android-phone-number-with-flags
i am trying to add Layout+View pager +list view,Layout+View pager working fine but View pager inside recycler view not scrolling.
it is possible...guide me
-Advance thanks
requirement Screenshot
How Can i set viewpager an recyclear view height dynamically
my xml code ...
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageView3"
android:background="#drawable/profile"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_marginTop="27dp" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabTextColor="#color/your_unselected_text_color"
app:tabSelectedTextColor="#color/your_selected_text_color"
android:layout_below="#+id/imageView3"
android:layout_alignParentStart="true" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/tabs"
android:layout_alignParentStart="true">
</android.support.v4.view.ViewPager>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/android.support.v7.widget.RecyclerView"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
First of all copy this class file in your project
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
public class ExpandableHeightListView extends ListView {
boolean expanded = false;
public ExpandableHeightListView(Context context) {
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public boolean isExpanded() {
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isExpanded()) {
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
}
Then use the ExpandableHeightlistview in scrollview like this
<ScrollView ...>
<RelativeLayout ...>
<viewpager></viewpager>
<com.example.ExpandableHeightListView ... />
<other view items />
</RelativeLayout>
Then setadpater of listview
and lastly and very important listview.setExpandable(true)
I've created a custom Linear layout in order to have "square" layout fitting the width of its parent but I'm having trouble positioning it with another LinearLayout.
I want the LinearLayout to be just below the SquareLinearLayout and I got this (both layout are top aligned):
I've tried android:parentAlignBottom="true" and android:gravity="bottom" but nothing works for me ...
Here is my layout xml :
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.dekajoo.rpg.MainActivity" >
<com.dekajoo.rpg.custom_layouts.SquareLinearLayout
android:id="#+id/game_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#f00" />
<android:LinearLayout
android:id="#+id/control_bar"
android:layout_width="match_parent"
android:layout_height="100dip"
android:background="#0f0"
android:gravity="center"
android:orientation="horizontal" />
</RelativeLayout>
And here is my SquareLinearLayout class :
package com.dekajoo.rpg.custom_layouts;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class SquareLinearLayout extends LinearLayout {
public SquareLinearLayout(Context context) {
super(context);
}
public SquareLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
/*public SquareView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}*/
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int size = width > height ? height : width;
setMeasuredDimension(size, size);
}
}
Thanks,
Add this to your LinearLayout, android:layout_below="#id/game_layout"
Android, when GridView nested in ScrollView or ListView, it's width will fill_parent even it's child is just one, i want it's width is wrap_content, any sulotion ? thanks.
the listview item xml like below :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/my_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp" >
</TextView>
<com.umeng.example.communitydemo.MGridView
android:id="#+id/my_gv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="#aaaaaa"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:padding="10dp"
android:verticalSpacing="5dp" />
</LinearLayout>
the MGridView is :
public class MGridView extends GridView {
public boolean hasScrollBar = true;
/**
* #param context
*/
public MGridView(Context context) {
this(context, null);
}
public MGridView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}
public MGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = heightMeasureSpec;
if (hasScrollBar) {
expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
two screen shot : http://pan.baidu.com/s/1c06Gfny。