App to choose layout according to situations - android

I am making a messaging android app, but my question is, how can I make the app choose either to pick the right hand layout or left hand layout? Like we see in messaging apps like WhatsApp, if I am the sender, my Message is wrapped in a right hand layout whilst the persons messages am chatting with are wrapped in a left handed layout, How can I achieve this type of Interface or layout I should say?
Below is my code, the app simple receives data from a remote database and puts it in a listview, using a custom adapter:
// the Data being set to the adapter
private ArrayList<ListItem> getListData() {
ArrayList<ListItem> listMockData = new ArrayList<ListItem>();
String[] username = mUsername.toArray(new String[mUsername.size()]);
String[] comments = Comment.toArray(new String[Comment.size()]);
for (int i = 0; i < username.length; i++) {
ListItem newsData = new ListItem();
newsData.setUsername(username[i]);
newsData.setmComment(comments[i]);
listMockData.add(newsData);
System.gc();
}
return listMockData;
}
And my custom adapter utilizing a single view:
public class CommentAdapter extends BaseAdapter{
private ArrayList<ListItem> listData;
private LayoutInflater layoutInflater;
ViewHolder holder;
public CommentAdapter(Context context, ArrayList<ListItem> listData) {
this.listData = listData;
notifyDataSetChanged();
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.singlecomment, null);
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.usernme);
holder.message = (TextView) convertView.findViewById(R.id.postCommentBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListItem newsItem = listData.get(position);
holder.username.setText(newsItem.getUsername());
holder.message.setText(newsItem.getmComment());
return convertView;
}
static class ViewHolder {
TextView username;
TextView message;
}
}

Assuming that your ListItem object has a field named isSender to check whether he is the sender or not.
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.singlecomment, null);
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.usernme);
holder.message = (TextView) convertView.findViewById(R.id.postCommentBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListItem newsItem = listData.get(position);
if(newsItem.getIsSender()) {
holder.usernameRight.setText(newsItem.getUsername());
holder.messageRight.setText(newsItem.getmComment());
holder.usernameLeft.setVisibility(View.GONE); // or something like that to hide
holder.messageLeft.setText(View.GONE);
} else {
holder.usernameLeft.setText(newsItem.getUsername());
holder.messageLeft.setText(newsItem.getmComment());
holder.usernameRight.setVisibility(View.GONE);
holder.messageRight.setText(View.GONE);
}
return convertView;
}

Related

Using holder for textview in listview

I'm implementing a ListView with 2 TextViews in it. The first TextView is the name of the product that I'm populating from a query. When I touch any item in the ListView a Dialog appears. When I confirm the Dialog I would like to change the second TextView text to string but whenever I do so every second Textview text changes. For example, if I have 3 items in list view and I click the first one only that item's text view should change instead of all three.
This is my base adapter code:
public class StrengthAdapter extends BaseAdapter {
private ArrayList<Strengths> list;
private LayoutInflater layoutInflater;
private static HashMap<Integer, String> selectedStrengthsMap = new HashMap<Integer, String>();
private String testing;
public StrengthAdapter(Context context, ArrayList<Strengths> list, String test) {
this.list = list;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.testing = test;
//HashMap<Integer, String> issuesStrengthsbrandNameIDMap = context
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null){
viewHolder = new ViewHolder();
//viewHolder.position = position;
convertView = layoutInflater.inflate(R.layout.strengthslistview, null);
viewHolder.strengthCheckBox = (TextView) convertView.findViewById(R.id.strengthsCheckBox);
viewHolder.chip = convertView.findViewById(R.id.chip);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.strengthCheckBox.setText(((Strengths) list.get(position)).getStrength_title());
viewHolder.chip.setText(testing);
//viewHolder.position = position;
return convertView;
}
public static HashMap<Integer, String> sendSelectedStrengthMap(){
return selectedStrengthsMap;
}
static class ViewHolder {
TextView strengthCheckBox;
TextView chip;
//int position;
}
}
This is how my I set my adapter initially:
strengthListView.setAdapter(new StrengthAdapter(StrengthOfDemandsView.this, strengthsList, "TEST"));
and this is how I set my adapter after closing the dialog:
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
strengthListView.setAdapter(new StrengthAdapter(StrengthOfDemandsView.this, strengthsList, "TEST123"));
}
});
You need to handle clicks inside of your adapter and not setting adapter every time click happens. It have to look like this:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null){
viewHolder = new ViewHolder();
//viewHolder.position = position;
convertView = layoutInflater.inflate(R.layout.strengthslistview, null);
viewHolder.strengthCheckBox = (TextView) convertView.findViewById(R.id.strengthsCheckBox);
viewHolder.chip = convertView.findViewById(R.id.chip);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.strengthCheckBox.setText(((Strengths) list.get(position)).getStrength_title());
convertView.setOnClickListener(
// show dialog here and then in positiveButton callback call
//viewHolder.chip.setText(testing);
);
return convertView;
}
First of all inflate your layout before creation of holder.
Then you need to define onclick behavior by implementing onclicklistener. I updated your getView method please implement this as follows:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null){
convertView = layoutInflater.inflate(R.layout.strengthslistview, null);
viewHolder = new ViewHolder();
//viewHolder.position = position;
viewHolder.strengthCheckBox = (TextView) convertView.findViewById(R.id.strengthsCheckBox);
viewHolder.chip = convertView.findViewById(R.id.chip);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.strengthCheckBox.setText(((Strengths) list.get(position)).getStrength_title());
viewHolder.chip.setText(testing);
//viewHolder.position = position;
convertView.setOnClickListener(
//you can do your job here what u want to do by clicking specific row
);
return convertView;
}
Also write your functionalities in the block I mentioned above in comments.

DIsplay first letter of string to another textview in Android

I am displaying a listview in which, the row item has two textview. The second textview is for the name of companies and the first textview is for the starting letter of the companies. How this can be achieved ? Need help !!
public class ExampleAdapter extends BaseAdapter {
Context context;
ArrayList<ExamplePojo> items = new ArrayList<>();
public ExampleAdapter(Context context, ArrayList<ExamplePojo> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return items.indexOf(items.get(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null){
convertView = inflater.inflate(R.layout.example_row_item, null);
holder = new ViewHolder();
holder.txtSentence = (TextView) convertView.findViewById(R.id.txtSentence);
holder.txtInitialLetter = (TextView) convertView.findViewById(R.id.txtInitialLetter);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
final ExamplePojo pojo = items.get(position);
holder.txtSentence.setText(pojo.getSentence());
holder.txtInitialLetter.setText(pojo.getSentence().charAt(0));
return convertView;
}
public class ViewHolder{
TextView txtSentence, txtInitialLetter;
}
}
Here is code for showing first character in first textview and complete name in other textview.Also put below lines in if(convertView== null) block
final ExamplePojo pojo = items.get(position);
holder.txtSentence.setText(pojo.getSentence());
holder.txtInitialLetter.setText(pojo.getSentence().substring(0, 1));

Android Listview with Image and Text

So I have a listview that has both text and images in it.
Everything about it works except when I am presented with the top row not having an image assigned to it.
rather than it using the placeholder image I have for rows that have no image assigned it takes the image of the current user.
The current user in this image is number 3, but his picture is also being shown for user 1.
here is my code for the CustomListAdapter, it grabs the PlayerItem which has players name and image url.
public class CustomListAdapter extends BaseAdapter {
private ArrayList<PlayerItem> listData;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context context, ArrayList<PlayerItem> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.rosterrow, null);
holder = new ViewHolder();
holder.playerNameView = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
PlayerItem playerItem = (PlayerItem) listData.get(position);
holder.playerNameView.setText(playerItem.getplayerName());
if ((holder.imageView != null) && (playerItem.getUrl() != null)) {
Picasso.with(null).load(playerItem.getUrl()).into(holder.imageView);
}
return convertView;
}
static class ViewHolder {
TextView playerNameView;
ImageView imageView;
}
}
Fixed it by adding
else {
holder.imageView.setImageResource(R.drawable.list_placeholder);
}

getview is not called in BaseAdapter

I have a problem with my custom adapter. the method getView() is not called. I searched on my friends "google" and "stackoverflow" but anything fix my problem.
public class custom_adapter extends BaseAdapter {
private List<Activities> listData;
private LayoutInflater layoutInflater;
public custom_adapter(Context context,
List<Activities> listActivity) {
this.listData = listActivity;
layoutInflater = layoutInflater.from(context);
Log.v("BaseAdapter", "custom_adapter");
}
#Override
public int getCount() {
Log.v("BaseAdapter - getCount", String.valueOf(listData.size()));
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("BaseAdapter", "getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_adapter, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.title);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.averageRatingBarActivitySearch);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Activities newsItem = (Activities) listData.get(position);
holder.name.setText(newsItem.getName());
holder.ratingBar.setRating(newsItem.getAverageMark());
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getPictureActivityString());
}
return convertView;
}
public static class ViewHolder {
TextView name;
RatingBar ratingBar;
ImageView imageView;
}
}
Furthermore, GetCount is not null !
I will be very glade if you can help me
Regards
K.L
For the purpose of handling List of some objects, extending generic ArrayAdapter may be better choice instead of just BaseAdapter. It will handle a lot of things for you. Your whole adapter class could look like.
public class ActivitiesAdapter extends ArrayAdapter<Activities>
{
private LayoutInflater layoutInflater;
public ActivitiesAdapter(Context context, List<Activities> objects)
{
super(context, 0, objects);
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("BaseAdapter", "getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_adapter, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.title);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.averageRatingBarActivitySearch);
holder.imageView = (ImageView) convertView.findViewById(R.id.thumbImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Activities newsItem = getItem(position);
holder.name.setText(newsItem.getName());
holder.ratingBar.setRating(newsItem.getAverageMark());
if (holder.imageView != null) {
new ImageDownloaderTask(holder.imageView).execute(newsItem.getPictureActivityString());
}
return convertView;
}
public static class ViewHolder {
TextView name;
RatingBar ratingBar;
ImageView imageView;
}
}
and of course you have to set this adapter to your ListView instance. Like
ActivitiesAdapter adapter = new ActivitiesAdapter(this, yourActivitiesList);
ListView listView = (ListView)findViewById(R.id.my_list_id);
listView.setAdapter(adapter);
or simply setListAdapter(adapter); if you are using ListActivity or ListFragment;
I had the same problem. Maybe, the problem is that you don't notify your adapter that you've changed data in the adapter. Try this code in your adapter:
#Override
public int getCount() {
return data.size();
}
And call notifyDataSetChanged(); when you change the data in Adapter.

How put <Spanned> into list.setAdapter?

Simple but little tricky, if I have
list.setAdapter(new ArrayAdapter<String>(this,R.layout.double_row, R.id.doubleRow, articleItemsHelper));
it works if articleItemsHelper is String, but I wanna have HTML formatting in there so when articleItemsHelper is type Spanned this (adapter) doesn't work.
ArrayList<Spanned> articleItemsHelper = new ArrayList<Spanned>();
What's the solution?
EDIT: here is the solution - custom adapter
private static class SpannedAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<Spanned> mArticleList;
public SpannedAdapter(Context context, ArrayList<Spanned> articleList) {
mInflater = LayoutInflater.from(context);
mArticleList = articleList;
}
public int getCount() {
return mArticleList.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.single_row, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.singleRow);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(mArticleList.get(position));
return convertView;
}
static class ViewHolder {
TextView text;
}
}
Then just regularly call
list.setAdapter(new SpannedAdapter(this, articleItemsHelper));
where
articleItemsHelper
is
ArrayList<Spanned>
Old thread but I found an other way to do it, it can help people:
simpleAdpt = new ArrayAdapter<Note>(this, R.layout.notelist, listeNotes ){
public View getView(int position, View view, ViewGroup viewGroup)
{
View v = super.getView(position, view, viewGroup);
Note n = (Note) this.getItem(position);
((TextView)v).setText(Html.fromHtml("<b>"+n.getTitre() + "</b> <br/>"+n.getNote()));
return v;
}
};
This is how ArrayAdapter set the text of the rows:
T item = getItem(position);
if (item instanceof CharSequence) {
text.setText((CharSequence)item);
} else {
text.setText(item.toString());
}
As you can see, what it would do in your case is to call the toString method, and that's why it does not work. So, go ahead and write your own adapter, you have no choice in this case.

Categories

Resources