I'm using RecyclerView to show elements of my data set. everything seems to work perfectly except I had two different types of items and I wish to change the Margin of each type to emphasize this slight difference.
to this end I used the viewtype of the adapter , however getLayoutParams() in onCreateViewHolder(ViewGroup parent, int viewType) seems to not give the correct params which I need to modify. recreating this param from scratch dynamically (with all the shadow and what not) seems unjustified.
here's my code:
private final static int TYPE1= 1;
private final static int TYPE2= 2;
#Override
public int getItemViewType(int position) {
if(data_set.get(position).isType1()) {
return TYPE1;
}
return TYPE2;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
int margin = parent.getContext().getResources().getDimensionPixelSize(R.dimen.end_margin);
if(viewType == TYPE1)
{
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) parent.getLayoutParams();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginStart(margin);
}else{
params.setMargins(margin,0,0,0);
}
v.setLayoutParams(params);
}
return new ViewHolder(v);
}
and heres my xml for item_layout
<android.support.v7.widget.CardView
android:id="#+id/item_card"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="vertical"
card_view:cardElevation="#dimen/cardview_default_elevation"
android:clickable="true"
card_view:cardCornerRadius="3dp"
android:nestedScrollingEnabled="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="rtl"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal">
<ProgressBar
android:id="#+id/img_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
<TextView
android:id="#+id/tv_contact_name"
android:gravity="end"
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v7.widget.CardView>
many thanks for any guidance provided.
When you call parent.getLayoutParams(); you are getting the params from the recyclerview.
If you want the parameter to the LinearLayout inside your xml file give it an id, and retrieve it inside your code. So something like this:
LinearLayout myLayout = v.findViewById(R.id.mylinearlayout);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) myLayout.getLayoutParams();
//do something with parameters
myLayout.setLayoutParams(params);
after some trial and error, I found a rather weird solution which most likely stems from that fact that I do not know the working of RecyclerViewwell.
at any rate I solved this problem by getting parent.getParent()'s CardView.LayoutParams and after modifications setting it to the view.
here's the modified code:
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
int endMargin = MyApplication.getSharedContext().getResources().getDimensionPixelSize(R.dimen.chat_end_margin);
int margin = MyApplication.getSharedContext().getResources().getDimensionPixelSize(R.dimen.chat_margin);
if(viewType == TYPE1)
{
ViewGroup parentView = (ViewGroup)parent.getParent();
CardView.LayoutParams params = (CardView.LayoutParams) (parentView.getLayoutParams());
params.setMargins(endMargin,margin,margin,margin);
v.setLayoutParams(params);
}
return new ViewHolder(v);
}
Related
I have a custom RecycleView and I am able to display the data in the RecycleViewsuccessfully. Now, I want to access the text view from the custom layout in order to make the change in later part of my code. I have provided the layout, RecycleViewadapter and the method I have tried to access the TextView. But I am getting NullPointerException with the view is null. How can I access the textview((R.id.zb) from Mylayout.xml in my main activity to modify RecycleView items?
My layout:
<android.support.v7.widget.CardView android:id="#+id/card_view1"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="#color/cardview_light_background"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3"
android:orientation="horizontal"
android:id="#+id/z">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Z "
style="#style/Base.TextAppearance.AppCompat.Large.Inverse"
android:layout_weight="1"
android:textColor="#color/colorPrimary"
android:gravity="center"
android:id="#+id/zn"/>
<TextView
android:id="#+id/zb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="buy"
android:textColor="#333"
style="#style/Base.TextAppearance.AppCompat.Medium.Inverse"/>
<TextView
android:id="#+id/zs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Sell"
android:textColor="#333"
style="#style/Base.TextAppearance.AppCompat.Medium.Inverse"/>
</LinearLayout>
</android.support.v7.widget.CardView>
RecycleView Adapter:
public class Adapter extends RecyclerView.Adapter<Adapter.Viewholder> {
private List<dispitems> m;
#NonNull
#Override
public Adapter.Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list1, parent, false);
return new Viewholder(itemView);
}
#Override
public void onBindViewHolder(#NonNull Adapter.Viewholder holder, int position) {
dispitems d = m.get(position);
holder.zb.setText(d.getZb());
holder.zs.setText(d.getZs());
holder.zn.setText(d.getZn());
}
#Override
public int getItemCount() {
return m.size();
}
Adapter(List<dispitems> m) {
this.m = m;
}
public class Viewholder extends RecyclerView.ViewHolder {
public TextView zb,zs,zn;
Viewholder(View itemView) {
super(itemView);
zn = (TextView) itemView.findViewById(R.id.zn);
zb = (TextView) itemView.findViewById(R.id.zb);
zs = (TextView) itemView.findViewById(R.id.zs);
}
}
}
I've tried the below options but it is showing the null pointer exception
Adapter.Viewholder row = (Adapter.Viewholder) recyclerView.findViewHolderForAdapterPosition(getCategoryPos(device));
row.zs.setTextColor(ContextCompat.getColor(this, R.color.colorAccent));
I have received the following exception.
java.lang.NullPointerException: Attempt to read from field 'android.widget.TextView cti.cryptotrackerindia.Adapter$Viewholder.zsell' on a null object reference
tried the below as well
View row = recyclerView.getLayoutManager().getChildAt(getCategoryPos(device));
Maybe I am not getting the question, but you should be able to just get the textview on onCreateViewHolder after you inflated the view.
public Adapter.Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list1, parent, false);
TextView txtView = (TextView )itemView.findViewById(R.id.zb);
return new Viewholder(itemView);
}
and then just store it as a member in the adapter.
If you want to update data displayed in RecyclerView, you should use notifyItemChanged(position, payload) to perform partial re-bind of ViewHolder.
Modifying layout of ViewHolder directly without referencing represented data can lead to discrepancy in displayed views, especially when You start scrolling your list and ViewHolders start being recycled and reused for other items.
I'm trying to follow the Android official doc for Creating Lists and Cards.
I found here that it was necessary to cast in TextView the ViewHolder but when I do it I have the following error: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.TextView
My Adapter
public class CardsViewAdapter extends RecyclerView.Adapter<CardsViewAdapter.ViewHolder> {
private Game[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.textViewName);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public CardsViewAdapter(Game[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public CardsViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_resume_game, parent, false);
// set the view's size, margins, paddings and layout parameters
//...
ViewHolder vh = new ViewHolder((TextView) v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset[position].getId_game());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.length;
}
}
My Custom View XML
<?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"
android:tag="cards main container">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="#color/blue_50"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="5dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="#+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
You have those 2 mixed up. Assuming that in
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_resume_game, parent, false);
the R.layout.cards_resume_game is LinearLayout, you should then have:
ViewHolder vh = new ViewHolder(v);
and have ViewHolder constructor accept a view:
public ViewHolder(View v) {
mTextView = (TextView) v.findViewById(R.id.some_text_view_id);
}
where some_text_view_id is a TextView in said layout, which will be fetched by findViewById()
In your adapter you are casting TextView to ViewHolder which isn't necessary, and you are also calling ViewHolder in a redundant way. Try this:
return new ViewHolder(v) instead of ViewHolder vh = new ViewHolder((TextView)
The reason you do not need this cast is because you are already casting mView under your ViewHolder constructor, or rather you're already defining the view it should expect.
Here's my data structure class:
public class FirstAidSteps implements Parcelable {
//These are the fields
private final String stepName;
private final ArrayList<String> steps;
.
.
.
}
Here's the adapter I've written:
public class StepsAdapter extends ArrayAdapter<FirstAidSteps> {
public StepsAdapter(Context context, ArrayList<FirstAidSteps> users) {
super(context, 0, users);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
FirstAidSteps steps = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
TextView stepName = (TextView) convertView.findViewById(R.id.step_heading);
stepName.setText(steps.getStepName());
return convertView;
}
}
Here's the XML for List Item:
<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/step_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:textSize="25sp" />
</LinearLayout>
I want to add the contents of ArrayList steps to the ListView. And I can't predefine the XML for steps because they can have any size.
I want the output something like below:
___________________
| StepName |
| Step |
| Step |
|-------------------|
| StepName |
| Step |
|-------------------|
| StepName |
|___________________|
So how to do this?
Assuming the number of steps is fairly small, I usually use a LinearLayout here, and add the necessary views.
To do this, you simply need to add a LinearLayout to your item view to contain the steps.
<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/step_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:textSize="25sp" />
<LinearLayout
android:id="#+id/steps"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Then you add steps to your item view via the adapter. Make sure you clear the previous steps in the view (also making sure you use the ViewHolder pattern).
public class StepsAdapter extends ArrayAdapter<FirstAidSteps> {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
v = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.stepName = (TextView) v.findViewById(R.id.step_heading);
holder.steps = (LinearLayout) v.findViewById(R.id.steps);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
final FirstAidSteps steps = getItem(position);
holder.stepName.setText(steps.getStepName());
holder.steps.removeAllViews();
for (String step : steps.getSteps()) {
holder.steps.addView(createStepView(step));
}
return v;
}
private static class ViewHolder {
TextView stepName;
LinearLayout steps;
}
}
In this case, createStepView() is an exercise for the reader.
Depending on your layout and possible number of steps, this may not be the best solution for you. If you will potentially have a lot of steps you may want to look into some sort of recycler view, or other recycling container.
cahnge your xml file to this
<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/step_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:textSize="25sp" />
<LinearLayout
android:id="#+id/steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
change steps to this
private final ArrayList<ArrayList<String>> steps;
private final ArrayList<String> stepsName;
and in adapter
public StepsAdapter(Context context, ArrayList<ArrayList<String>> steps, ArrayList<String> stepsName) {
super(context, 0, steps, stepsName);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
TextView stepName = (TextView) convertView.findViewById(R.id.step_heading);
LinearLayout mLinearLayout = (LinearLayout) v.findViewById(R.id.steps);
stepName.setText(stepsName.get(position));
mLinearLayout.removeAllViews();
ArrayList<String> single_step= steps.get(position);
if(single_step.size() > 0){
for (int size =0; size <single_step.size(); size++) {
TextView text = new TextView(this);
text.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
text.setGravity(Gravity.CENTER);
text.setPadding(5, 2, 5, 2);
text.setText(single_step.get(size));
mLinearLayout.addView(text);
}
}
return convertView;
}
I have this weird issue with my adapter that no methods are called.. The constructor works, it stops there if I have a breakpoint but from there, nothing.. onCreateViewHolder doesn't get called and neither onBindViewHolder and not even getItemCount.. I tried everything I could find online but nothing seems to be working so I don't know what to do. Any suggestions? Here's my code:
Fragment:
public class FragmentPackageDetails extends Fragment {
//other vars
RecyclerView rvPackageDetails;
DatabaseHandler database;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle args = getArguments();
String temp = args.getString(KEY_TRACKER_CODE);
View v = inflater.inflate(R.layout.fragment_package_details_new, container, false);
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
rvPackageDetails = (RecyclerView) view.findViewById(R.id.rvPackageDetails);
rvPackageDetails.setLayoutManager(new LinearLayoutManager(getActivity()));
database = new DatabaseHandler(getActivity());
selectedPackage = database.getPackage(trackerCode);
RecyclerView.Adapter adapter = new MyAdapter(selectedPackage.getRecords());
rvPackageDetails.setAdapter(adapter);
}
//other methods in class
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<TrackingRecordCheckedOut> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView tvPackageDetailsRowDayOfWeek, tvPackageDetailsRowDayOfMonth, tvPackageDetailsRowNameOfMonth,
tvPackageDetailsRowDetailsTitle, tvPackageDetailsRowDetailsDescription, tvPackageDetailsRowDetialsTime;
public ViewHolder(View v) {
super(v);
tvPackageDetailsRowDayOfWeek = (TextView) v.findViewById(R.id.tvPackageDetailsRowDayOfWeek);
tvPackageDetailsRowDayOfMonth = (TextView) v.findViewById(R.id.tvPackageDetailsRowDayOfMonth);
tvPackageDetailsRowNameOfMonth = (TextView) v.findViewById(R.id.tvPackageDetailsRowNameOfMonth);
tvPackageDetailsRowDetailsTitle = (TextView) v.findViewById(R.id.tvPackageDetailsRowDetialsTime);
tvPackageDetailsRowDetailsDescription = (TextView) v.findViewById(R.id.tvPackageDetailsRowDetailsDescription);
tvPackageDetailsRowDetialsTime = (TextView) v.findViewById(R.id.tvPackageDetailsRowDetialsTime);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<TrackingRecordCheckedOut> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_list_item, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
TrackingRecordCheckedOut tr = mDataset.get(position);
holder.tvPackageDetailsRowDayOfWeek.setText(tr.getDayOfWeek());
holder.tvPackageDetailsRowDayOfMonth.setText(tr.getDayOfWeek());
holder.tvPackageDetailsRowNameOfMonth.setText(tr.getMonthOfYear());
holder.tvPackageDetailsRowDetailsTitle.setText(tr.getTitle());
holder.tvPackageDetailsRowDetailsDescription.setText(tr.getDetails());
holder.tvPackageDetailsRowDetialsTime.setText(tr.getTimeOfDay());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
Fragment Layout:
<?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">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvPackageDetails"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
RecyclerView Row Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llPackageDetailsRecyclerViewRow"
android:layout_width="match_parent"
android:layout_height="96dip"
android:orientation="horizontal"
android:weightSum="100">
<LinearLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="20"
android:orientation="vertical"
android:weightSum="10">
<TextView
android:id="#+id/tvPackageDetailsRowDayOfWeek"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="3"/>
<TextView
android:id="#+id/tvPackageDetailsRowDayOfMonth"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="4"/>
<TextView
android:id="#+id/tvPackageDetailsRowNameOfMonth"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="3"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="80"
android:orientation="vertical">
<TextView
android:id="#+id/tvPackageDetailsRowDetailsTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"/>
<TextView
android:id="#+id/tvPackageDetailsRowDetailsDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"/>
<TextView
android:id="#+id/tvPackageDetailsRowDetialsTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"/>
</LinearLayout>
</LinearLayout>
I had this same issue where neither onCreateViewHolder or onBindViewHolder were being called. Saving a reference to Context in the constructor of your Adapter, and then changing your onCreateViewHolder method to use the saved reference to Context instead of doing parent.getContext() should fix it:
private Context mContext;
public MyAdapter(Context context, ArrayList<TrackingRecordCheckedOut> myDataset) {
mDataset = myDataset;
mContext = context;
}
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view using saved reference to Context (mContext)
View v = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_list_item, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
I looked at your code don't really see an issue unfortunately. One thing that might be problematic is that in you ViewHolder constructor you call super(v). You might need to call super((LinearLayout)v). That might not make a difference though.
Good luck!
I have a conversation page with bubble and thumbnail user image, I have problem with thumbnail position: when I send text thumbnail must show on the right and when my friend sent text his thumbnail must show on the left
My XML item is :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp" >
<LinearLayout
android:id="#+id/wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0.5dp" >
<ImageView
android:id="#+id/icon"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="#drawable/user_four"
android:padding="0dp" />
<TextView
android:id="#+id/comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dip"
android:textColor="#2e2e2e"
android:paddingLeft="10dp" />
</LinearLayout>
</RelativeLayout>
and my Java code is :
public class ChatArrayAdapter extends ArrayAdapter<Comment> {
private TextView countryName;
private List<Comment> countries = new ArrayList<Comment>();
private LinearLayout wrapper;
#Override
public void add(Comment object) {
countries.add(object);
super.add(object);
}
public ChatArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public int getCount() {
return this.countries.size();
}
public Comment getItem(int index) {
return this.countries.get(index);
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.listitem_chat, parent, false);
}
wrapper = (LinearLayout) row.findViewById(R.id.wrapper);
Comment coment = getItem(position);
countryName = (TextView) row.findViewById(R.id.comment);
countryName.setText(coment.comment);
countryName.setBackgroundResource(coment.left ? R.drawable.other_bubble : R.drawable.own_bubble);
wrapper.setGravity(coment.left ? Gravity.LEFT : Gravity.RIGHT);
return row;
}
public Bitmap decodeToBitmap(byte[] decodedByte) {
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
}
If you know in getView() method that the text is your's or your friend's you can change gravity attribute to left or right, depending on the condition, of the linear layout.
Use seperate layout for left and right then inflate it with the correct layout in your get view