RecyclerView with different layouts - android

when i use this
#Override
public int getItemViewType(int position) {
return position;
}
my RecyclerView work without problem
now i want to use multi layout on it i use this
#Override
public int getItemViewType(int position) {
int type = -1;
if(mMessages.get(position).getDir().equals("left")) type = 1;
else if(mMessages.get(position).getDir().equals("right")) type = 0;
else if(mMessages.get(position).getDir().equals("typing")) type = 2;
return type;
//return position;
}
the problem when i used it's and scroll to top and back to bottom or just scrolling
its reorder item in RecyclerView like make the first item on it the last one or on middle or every where not i the correct position
just if i back to the first code of getItemViewType its work without
problem but i cant use multi layout
my full code
public class MessageAdapter1 extends RecyclerView.Adapter<MessageAdapter1.ViewHolder> {
private List<MessageList> mMessages;
private int[] mUsernameColors;
private Context context;
public MessageAdapter1(Context context, List<MessageList> messages) {
mMessages = messages;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
switch (viewType) {
case 0:
layout = R.layout.right_message;
break;
case 1:
layout = R.layout.left_message;
break;
case 2:
layout = R.layout.message_left;
break;
}
View v = LayoutInflater.from(parent.getContext()).inflate(layout , parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
MessageList message = mMessages.get(position);
//viewHolder.setMessage(message.getMessage());
//viewHolder.setUsername(message.getUsername());
viewHolder.setGroupMessage(message);
}
#Override
public int getItemCount() {
return mMessages.size();
}
#Override
public int getItemViewType(int position) {
int type = -1;
if(mMessages.get(position).getDir().equals("left")) type = 1;
else if(mMessages.get(position).getDir().equals("right")) type = 0;
else if(mMessages.get(position).getDir().equals("typing")) type = 2;
return type;
//return position;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private LinearLayout groupMessage;
//private ImageView typing;
public ViewHolder(View itemView) {
super(itemView);
groupMessage = (LinearLayout)itemView.findViewById(R.id.messages);
}
public void setGroupMessage(MessageList m) {
if (null == groupMessage) return;
int i = 0;
if(m.getMessageStatus() == false){
m.setMessageStatus(true);
for (String message : m.getMessageList()) {
//TextView text = new TextView(activity);
TextView text = new MyTextView(context);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
p.setMargins(0, 0, 0, 2);
if (m.getDir().equals("left")) {
text.setTextColor(Color.BLACK);
p.gravity = Gravity.LEFT;
if(m.getMessageList().size() == 1){
text.setBackgroundResource(R.drawable.message_left_default);
}
else if (i == 0) {
text.setBackgroundResource(R.drawable.message_left_first);
} else if (i + 1 == m.getMessageList().size()) {
text.setBackgroundResource(R.drawable.message_left_last);
} else {
text.setBackgroundResource(R.drawable.message_left);
}
} else{
p.gravity = Gravity.RIGHT;
text.setTextColor(Color.WHITE);
if(m.getMessageList().size() == 1){
text.setBackgroundResource(R.drawable.message_right_default);
}
else if (i == 0) {
text.setBackgroundResource(R.drawable.message_right_first);
} else if (i + 1 == m.getMessageList().size()) {
text.setBackgroundResource(R.drawable.message_right_last);
} else {
text.setBackgroundResource(R.drawable.message_right);
}
}
text.setLayoutParams(p);
text.setText(message);
text.setPadding(8, 8, 8, 8);
text.setTextSize(18f);
//text.setTextAppearance(context, android.R.style.TextAppearance_Large);
groupMessage.addView(text);
i++;
}
}
}
}
}

I solve it by remove
int type = -1;
if(mMessages.get(position).getDir().equals("left")) type = 1;
else if(mMessages.get(position).getDir().equals("right")) type = 0;
else if(mMessages.get(position).getDir().equals("typing")) type = 2;
return type;
from
getItemViewType
and return position
and put the first code
int type = -1;
if(mMessages.get(position).getDir().equals("left")) type = 1;
else if(mMessages.get(position).getDir().equals("right")) type = 0;
else if(mMessages.get(position).getDir().equals("typing")) type = 2;
return type;
in onCreateViewHolder and use viewType as the current position

Related

How to add margin to 2x2 items view in grid view?

Want to add margin to gridview in the following manner.
Left margin for 2,4, 2,9, 12,14,..
Right margin for 3,5, 8,10, 13,15,..
Here is my code snippet which I tried to set margin to 2x2 items in grid view...
i.e positions - ..,2,3,4,5,..,7,8,9,10,..,12,13,14,15,..,17,18,19,20,.. like wise.
for 2,3,4,5 & 12,13,14,15,.. Getting the expected output. but my case failed for 7,8,9,10 & 17,18,19,20 series.
Help me to solve this. Confused to solve this mathematical puzzle.
Thanks in advance.
public class BoxFeedAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<BoxFeedResult> boxFeedResults;
private Context mContext;
private RecyclerViewItemClickListener viewItemClickListener;
private final int LARGE_TYPE = 0;
private final int SMALL_TYPE = 1;
private final int PROGRESS_TYPE = 2;
private int GRID_VIEW_MARGIN_LEFT = 0;
private int GRID_VIEW_MARGIN_RIGHT = 0;
private int GRID_VIEW_MARGIN_TOP = 0;
private int GRID_VIEW_MARGIN_BOTTOM = 0;
private int GRID_VIEW_ROW_MARGIN = 0;
public BoxFeedAdapter(Context context, RecyclerViewItemClickListener viewItemClickListener) {
this.mContext = context;
this.viewItemClickListener = viewItemClickListener;
boxFeedResults = new ArrayList<>();
GRID_VIEW_MARGIN_LEFT = context.getResources().getDimensionPixelOffset(R.dimen.empty_dimen);
GRID_VIEW_MARGIN_RIGHT = context.getResources().getDimensionPixelOffset(R.dimen.empty_dimen);
GRID_VIEW_MARGIN_TOP = context.getResources().getDimensionPixelOffset(R.dimen.channel_row_padding);
GRID_VIEW_MARGIN_BOTTOM = context.getResources().getDimensionPixelOffset(R.dimen.empty_dimen);
GRID_VIEW_ROW_MARGIN = context.getResources().getDimensionPixelOffset(R.dimen.channel_row_padding_left);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == SMALL_TYPE) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_box_feed_series_banner, null);
return new BoxFeedSeriesListViewHolder(layoutView);
} else if (viewType == LARGE_TYPE) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_box_feed_episode_banner, null);
return new BoxFeedEpisodeViewHolder(layoutView);
} else {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.progress_item, null);
return new ProgressViewHolder(layoutView);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof BoxFeedSeriesListViewHolder) {
StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setFullSpan(false);
if ((position - 1) % 2 == 0) {
layoutParams.setMargins(GRID_VIEW_ROW_MARGIN, GRID_VIEW_MARGIN_TOP, GRID_VIEW_MARGIN_RIGHT, GRID_VIEW_MARGIN_BOTTOM);
} else {
layoutParams.setMargins(GRID_VIEW_MARGIN_LEFT, GRID_VIEW_MARGIN_TOP, GRID_VIEW_ROW_MARGIN, GRID_VIEW_MARGIN_BOTTOM);
}
holder.itemView.setLayoutParams(layoutParams);
final BoxFeedResult singleFeed = boxFeedResults.get(position);
final BoxFeedSeriesListViewHolder viewHolder = (BoxFeedSeriesListViewHolder) holder;
Glide.with(mContext)
.load(singleFeed.getA4MediumUrl())
.placeholder(R.drawable.bg_black)
.into(viewHolder.seriesImage);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, singleFeed.getId(), Toast.LENGTH_SHORT).show();
viewItemClickListener.onItemClickListioner(singleFeed, viewHolder.seriesImage, position);
}
});
} else if (holder instanceof BoxFeedEpisodeViewHolder) {
StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setFullSpan(true);
holder.itemView.setLayoutParams(layoutParams);
final BoxFeedResult singleFeed = boxFeedResults.get(position);
final BoxFeedEpisodeViewHolder viewHolder = (BoxFeedEpisodeViewHolder) holder;
Glide.with(mContext)
.load(singleFeed.getAspectMediumUrl())
.placeholder(R.drawable.bg_black)
.into(viewHolder.episodeImage);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, singleFeed.getId(), Toast.LENGTH_SHORT).show();
}
});
} else {
StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setFullSpan(true);
holder.itemView.setLayoutParams(layoutParams);
}
}
#Override
public int getItemCount() {
return boxFeedResults.size();
}
#Override
public int getItemViewType(int position) {
switch (boxFeedResults.get(position).getTileType()) {
case “large":
return LARGE_TYPE;
case “small":
return SMALL_TYPE;
default:
return PROGRESS_TYPE;
}
}
public void addList(List<BoxFeedResult> feedResults) {
this.boxFeedResults = feedResults;
notifyDataSetChanged();
}
}
Expected output is

Messages not appears correctly in recycler view

I'm writing a messaging app that show mine and other message in RecyclerView.
White background message is Mine message and colored messages is other message.
When each message is sequentially like " Mine Message, Other Message, ..." the recycler view shows correct.
Like below.
But when message sequence like "Other message, Other message, Mine message" the recycler view shows Mine message as other and vice versa.
Like below
I used this code for onBindViewHolder
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
View v;
int width = context.getResources().getDisplayMetrics().widthPixels;
LinearLayout.LayoutParams layoutParams;
layoutParams = new LinearLayout.LayoutParams((int) (width * 0.75), ViewGroup.LayoutParams.WRAP_CONTENT);
if(getItemViewType(i) == MINE){
v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_message_view_mine, viewGroup, false);
v.setX((float) (width * 0.23));
}else {
v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_message_view, viewGroup, false);
v.setX(0);
}
layoutParams.setMargins(5, 5, 5, 5);
v.setLayoutParams(layoutParams);
return new ViewHolder(v);
}
#Override
public int getItemViewType(int position) {
Log.e("pos", position + "");
try{
if(items.get(position).isResponse()){
return MINE;
}else {
return OTHERS;
}
}catch (Exception e){
e.printStackTrace();
return OTHERS;
}
}
#Override
public void onBindViewHolder(final ViewHolder viewHolder, int i) {
if(getItemViewType(i) == OTHERS){
if(items.get(i).getResponse() != null){
viewHolder.layout.setBackgroundColors(R.color.green_1, R.color.green_2);
}else {
if(items.get(i).getDate() - System.currentTimeMillis() /1000 > 100){
viewHolder.layout.setBackgroundColors(R.color.red_1, R.color.red_2);
}else {
viewHolder.layout.setBackgroundColors(R.color.yellow_1, R.color.yellow_2);
}
}
}
if(!items.get(i).isResponse()){
if(items.get(i).getResponse() != null){
viewHolder.layout.setBackgroundColors(R.color.green_1, R.color.green_2);
}else {
int type = General.currentUser.getCurrentRole().getType();
int timeOut = 0;
if(type == Role.OPERATOR){
timeOut = General.operatorTimeOut;
}else if(type == Role.EXPERT || type == Role.CO_EXPERT){
timeOut = General.expertTimeOut;
}else if(type == Role.SENDER){
timeOut = General.senderTimeOut;
}else if(type == Role.VERIFIER){
timeOut = General.verifierTimeOut;
}
if((System.currentTimeMillis() / 1000) - items.get(i).getDate() > timeOut){
viewHolder.layout.setBackgroundColors(R.color.red_1, R.color.red_2);
}else {
viewHolder.layout.setBackgroundColors(R.color.yellow_1, R.color.yellow_2);
}
}
}else {
viewHolder.layout.setBackgroundColors(R.color.white, R.color.grey);
}
if(items.get(i).getType() == Message.TYPE_VOICE && items.get(i).getVoice() != null){
viewHolder.layoutVoice.setVisibility(View.VISIBLE);
viewHolder.tvText.setVisibility(View.GONE);
//if(items.get(i).getVoice().get)
File voice = new File(context.getCacheDir().getAbsolutePath() + "/" + items.get(i).getVoice().getId());
if(voice.exists()){
viewHolder.playerView.setVisibility(View.VISIBLE);
viewHolder.ivVoice.setVisibility(View.GONE);
if(playerItem != -1){
if(playerItem == i){
viewHolder.playerView.startAnimation((int) items.get(i).getVoice().getLength(), new PlayerView.PlayerViewListener() {
#Override
public void onPlayerFinished() {
}
});
}else {
viewHolder.playerView.stopAnimation();
}
}
}else {
viewHolder.playerView.setVisibility(View.GONE);
viewHolder.ivVoice.setVisibility(View.VISIBLE);
}
viewHolder.tvVoiceVolume.setText((items.get(i).getVoice().getVolume() / 1024) + " KB");
viewHolder.tvVoiceLength.setText((items.get(i).getVoice().getLength() /60) + ":" + (items.get(i).getVoice().getLength() %60) + " s");
}else {
viewHolder.layoutVoice.setVisibility(View.GONE);
viewHolder.tvText.setVisibility(View.VISIBLE);
viewHolder.tvText.setText(items.get(i).getText());
}
if(items.get(i).isResponse()){
viewHolder.ivSent.setVisibility(View.VISIBLE);
if(items.get(i).getSendStatus() == Message.SENT){
viewHolder.ivSent.setImageResource(R.drawable.ic_check_black_24dp);
viewHolder.ivSent.setColorFilter(ContextCompat.getColor(context, android.R.color.holo_green_dark));
}else if(items.get(i).getSendStatus() == Message.SENDING) {
viewHolder.ivSent.setImageResource(R.drawable.ic_query_builder_black_24dp);
viewHolder.ivSent.setColorFilter(Color.GRAY);
}else if(items.get(i).getSendStatus() == Message.FAILED){
viewHolder.ivSent.setImageResource(R.drawable.ic_error_black_24dp);
viewHolder.ivSent.setColorFilter(Color.RED);
}
}else {
if(items.get(i).getUnder_user_role_process1() > 0){
viewHolder.ivSent.setVisibility(View.VISIBLE);
viewHolder.ivSent.setImageResource(R.drawable.ic_verified_user_black_24dp);
viewHolder.ivSent.setColorFilter(ContextCompat.getColor(context, android.R.color.holo_green_dark));
}else {
viewHolder.ivSent.setVisibility(View.INVISIBLE);
}
}
Date date = new Date(items.get(i).getDate() * 1000L); // *1000 is to convert seconds to milliseconds
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm", Locale.ENGLISH); // the format of your date
sdf.setTimeZone(TimeZone.getTimeZone("GMT-4:30")); // give a timezone reference for formatting (see comment at the bottom
String formattedDate = sdf.format(date);
viewHolder.tvDate.setText(formattedDate);
}
What's problem?
I first think about the users not have a like "UserID" so then when u type 2 messages in row u will get a bug like every message will be on one side. And why u use recyclerView? not better is create a layout with like "Scroll View" and adding for this a views(messages) ?
private long createRandomId() {
char[] chars = "123456789".toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < 10; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
return Long.parseLong(sb.toString());
}
I also encounter that problem sir but I solve it using separate view holders.
#Override
public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
UserViewHolder holder = null ;
int layoutRes = 0;
switch (viewType) {
case CURRENT_USER_VIEW:
layoutRes = R.layout.current_user_view_model;
view = inflater.inflate(layoutRes, parent, false);
holder = new CurrentUserHolder(view);
break;
case OTHER_USER_VIEW:
layoutRes = R.layout.sender_user_view_model;
view = inflater.inflate(layoutRes, parent, false);
holder = new SenderUserHolder(view);
break;
}
return holder;
}
public abstract class UserViewHolder extends RecyclerView.ViewHolder{
public UserViewHolder(View itemView) {
super(itemView);
}
}
public class SenderUserHolder extends UserViewHolder{
public TextView message;
public TextView dateSent;
public ImageView senderImage;
public final View mView;
public View contSender;
public SenderUserHolder(View itemView) {
super(itemView);
mView = itemView;
contSender = itemView.findViewById(R.id.cont_sender);
message = (TextView)mView.findViewById(R.id.tv_message);
dateSent = (TextView)mView.findViewById(R.id.tv_send_date);
senderImage = (ImageView)mView.findViewById(R.id.iv_send_image);
}
}
public class CurrentUserHolder extends UserViewHolder{
public TextView message;
public TextView dateSent;
public final View mView;
public View cont;;
public CurrentUserHolder(View itemView) {
super(itemView);
mView = itemView;
cont = mView.findViewById(R.id.cont_current);
message = (TextView)mView.findViewById(R.id.tv_message);
dateSent = (TextView)mView.findViewById(R.id.tv_send_date);
}
}
I solved problem.
onCreateViewHolder's second parameter is viewType not a position.
So the i in onCreateViewHolder is viewType. So I changed if(getItemViewType(i) == MINE) to if(i == MINE) after it every thing gone ok.

Adapter-Showing view only when there is a change in a value

Below is my complete adapter class of sendbird chatting.Currently date with time is displayed with every message.viewHolder.getView("left_time") and viewHolder.getView("right_time") are views for displaying date with time and it is calculated in method getDisplayDateTime.I want date with time to be displayed only when there is a change in date.For example if there is set of messages dated 23rd june then date with time should be displayed only for the first message with date 23rd june.
I tried doing that by detecting whenever there is a change in date by storing date in xyz variable and comparing it with date of every message and whenever they are unequal then making date view of that message visible and assigning the new date to xyz variable for comparison with future messages.But this approach fails when i scroll down and scroll up list.
What is the ideal approach for achieving this?
public class SendBirdMessagingAdapter extends BaseAdapter {
private static final int TYPE_UNSUPPORTED = 0;
private static final int TYPE_MESSAGE = 1;
private static final int TYPE_SYSTEM_MESSAGE = 2;
private static final int TYPE_FILELINK = 3;
private static final int TYPE_BROADCAST_MESSAGE = 4;
private static final int TYPE_TYPING_INDICATOR = 5;
private final Context mContext;
private final LayoutInflater mInflater;
private final ArrayList<Object> mItemList;
private Hashtable<String, Long> mReadStatus;
private Hashtable<String, Long> mTypeStatus;
private List<MessagingChannel.Member> mMembers;
private long mMaxMessageTimestamp = Long.MIN_VALUE;
private long mMinMessageTimestamp = Long.MAX_VALUE;
public SendBirdMessagingAdapter(Context context) {
mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mItemList = new ArrayList<Object>();
mReadStatus = new Hashtable<String, Long>();
mTypeStatus = new Hashtable<String, Long>();
}
#Override
public int getCount() {
return mItemList.size() + ((mTypeStatus.size() <= 0) ? 0 : 1);
}
#Override
public Object getItem(int position) {
if (position >= mItemList.size()) {
ArrayList<String> names = new ArrayList<String>();
for (MessagingChannel.Member member : mMembers) {
if (mTypeStatus.containsKey(member.getId())) {
names.add(member.getName());
}
}
return names;
}
return mItemList.get(position);
}
public void delete(Object object) {
mItemList.remove(object);
}
public void clear() {
mMaxMessageTimestamp = Long.MIN_VALUE;
mMinMessageTimestamp = Long.MAX_VALUE;
mReadStatus.clear();
mTypeStatus.clear();
mItemList.clear();
}
public void resetReadStatus(Hashtable<String, Long> readStatus) {
mReadStatus = readStatus;
}
public void setReadStatus(String userId, long timestamp) {
if (mReadStatus.get(userId) == null || mReadStatus.get(userId) < timestamp) {
mReadStatus.put(userId, timestamp);
}
}
public void setTypeStatus(String userId, long timestamp) {
if (userId.equals(SendBird.getUserId())) {
return;
}
if (timestamp <= 0) {
mTypeStatus.remove(userId);
} else {
mTypeStatus.put(userId, timestamp);
}
}
#Override
public long getItemId(int position) {
return position;
}
public void addMessageModel(MessageModel messageModel) {
if (messageModel.isPast()) {
mItemList.add(0, messageModel);
} else {
mItemList.add(messageModel);
}
updateMessageTimestamp(messageModel);
}
private void updateMessageTimestamp(MessageModel model) {
mMaxMessageTimestamp = mMaxMessageTimestamp < model.getTimestamp() ? model.getTimestamp() : mMaxMessageTimestamp;
mMinMessageTimestamp = mMinMessageTimestamp > model.getTimestamp() ? model.getTimestamp() : mMinMessageTimestamp;
}
public long getMaxMessageTimestamp() {
return mMaxMessageTimestamp == Long.MIN_VALUE ? Long.MAX_VALUE : mMaxMessageTimestamp;
}
public long getMinMessageTimestamp() {
return mMinMessageTimestamp == Long.MAX_VALUE ? Long.MIN_VALUE : mMinMessageTimestamp;
}
public void setMembers(List<MessagingChannel.Member> members) {
mMembers = members;
}
#Override
public int getItemViewType(int position) {
if (position >= mItemList.size()) {
return TYPE_TYPING_INDICATOR;
}
Object item = mItemList.get(position);
if (item instanceof Message) {
return TYPE_MESSAGE;
} else if (item instanceof FileLink) {
return TYPE_FILELINK;
} else if (item instanceof SystemMessage) {
return TYPE_SYSTEM_MESSAGE;
} else if (item instanceof BroadcastMessage) {
return TYPE_BROADCAST_MESSAGE;
}
return TYPE_UNSUPPORTED;
}
#Override
public int getViewTypeCount() {
return 6;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
final Object item = getItem(position);
if (convertView == null || ((ViewHolder) convertView.getTag()).getViewType() != getItemViewType(position)) {
viewHolder = new ViewHolder();
viewHolder.setViewType(getItemViewType(position));
switch (getItemViewType(position)) {
case TYPE_UNSUPPORTED:
convertView = new View(mInflater.getContext());
convertView.setTag(viewHolder);
break;
case TYPE_MESSAGE: {
TextView tv;
CircularImageView iv;
View v;
convertView = mInflater.inflate(R.layout.sendbird_view_messaging_message, parent, false);
v = convertView.findViewById(R.id.left_container);
viewHolder.setView("left_container", v);
iv = (CircularImageView) convertView.findViewById(R.id.img_left_thumbnail);
viewHolder.setView("left_thumbnail", iv);
tv = (TextView) convertView.findViewById(R.id.txt_left);
viewHolder.setView("left_message", tv);
tv = (TextView) convertView.findViewById(R.id.txt_left_name);
viewHolder.setView("left_name", tv);
tv = (TextView) convertView.findViewById(R.id.txt_left_time);
viewHolder.setView("left_time", tv);
v = convertView.findViewById(R.id.right_container);
viewHolder.setView("right_container", v);
iv = (CircularImageView) convertView.findViewById(R.id.img_right_thumbnail);
viewHolder.setView("right_thumbnail", iv);
tv = (TextView) convertView.findViewById(R.id.txt_right);
viewHolder.setView("right_message", tv);
tv = (TextView) convertView.findViewById(R.id.txt_right_name);
viewHolder.setView("right_name", tv);
tv = (TextView) convertView.findViewById(R.id.txt_right_time);
viewHolder.setView("right_time", tv);
tv = (TextView) convertView.findViewById(R.id.txt_right_status);
viewHolder.setView("right_status", tv);
convertView.setTag(viewHolder);
break;
}
case TYPE_SYSTEM_MESSAGE: {
convertView = mInflater.inflate(R.layout.sendbird_view_system_message, parent, false);
viewHolder.setView("message", convertView.findViewById(R.id.txt_message));
convertView.setTag(viewHolder);
break;
}
case TYPE_BROADCAST_MESSAGE: {
convertView = mInflater.inflate(R.layout.sendbird_view_system_message, parent, false);
viewHolder.setView("message", convertView.findViewById(R.id.txt_message));
convertView.setTag(viewHolder);
break;
}
case TYPE_FILELINK: {
TextView tv;
CircularImageView civ;
ImageView iv;
View v;
convertView = mInflater.inflate(R.layout.sendbird_view_messaging_filelink, parent, false);
v = convertView.findViewById(R.id.left_container);
viewHolder.setView("left_container", v);
civ = (CircularImageView) convertView.findViewById(R.id.img_left_thumbnail);
viewHolder.setView("left_thumbnail", civ);
iv = (ImageView) convertView.findViewById(R.id.img_left);
viewHolder.setView("left_image", iv);
tv = (TextView) convertView.findViewById(R.id.txt_left_name);
viewHolder.setView("left_name", tv);
tv = (TextView) convertView.findViewById(R.id.txt_left_time);
viewHolder.setView("left_time", tv);
v = convertView.findViewById(R.id.right_container);
viewHolder.setView("right_container", v);
civ = (CircularImageView) convertView.findViewById(R.id.img_right_thumbnail);
viewHolder.setView("right_thumbnail", civ);
iv = (ImageView) convertView.findViewById(R.id.img_right);
viewHolder.setView("right_image", iv);
tv = (TextView) convertView.findViewById(R.id.txt_right_name);
viewHolder.setView("right_name", tv);
tv = (TextView) convertView.findViewById(R.id.txt_right_time);
viewHolder.setView("right_time", tv);
tv = (TextView) convertView.findViewById(R.id.txt_right_status);
viewHolder.setView("right_status", tv);
convertView.setTag(viewHolder);
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new AlertDialog.Builder(mContext)
.setTitle("Foodvite")
.setMessage("Do you want to download this file?")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
downloadUrl((FileLink) item, mContext);
} catch (IOException e) {
e.printStackTrace();
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.create()
.show();
}
});
break;
}
case TYPE_TYPING_INDICATOR: {
convertView = mInflater.inflate(R.layout.sendbird_view_typing_indicator, parent, false);
viewHolder.setView("message", convertView.findViewById(R.id.txt_message));
convertView.setTag(viewHolder);
break;
}
}
}
viewHolder = (ViewHolder) convertView.getTag();
switch (getItemViewType(position)) {
case TYPE_UNSUPPORTED:
break;
case TYPE_MESSAGE:
Message message = (Message) item;
if (message.getSenderId().equals(SendBird.getUserId())) {
viewHolder.getView("left_container", View.class).setVisibility(View.GONE);
viewHolder.getView("right_container", View.class).setVisibility(View.VISIBLE);
displayUrlImage(viewHolder.getView("right_thumbnail", CircularImageView.class), message.getSenderImageUrl(), true);
viewHolder.getView("right_name", TextView.class).setText(message.getSenderName());
viewHolder.getView("right_message", TextView.class).setText(message.getMessage());
viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp()));
int readCount = 0;
for (String key : mReadStatus.keySet()) {
if (key.equals(message.getSenderId())) {
readCount += 1;
continue;
}
if (mReadStatus.get(key) >= message.getTimestamp()) {
readCount += 1;
}
}
if (readCount < mReadStatus.size()) {
if (mReadStatus.size() - readCount > 1) {
viewHolder.getView("right_status", TextView.class).setText("Unread " + (mReadStatus.size() - readCount));
} else {
viewHolder.getView("right_status", TextView.class).setText("Unread");
}
} else {
viewHolder.getView("right_status", TextView.class).setText("");
}
viewHolder.getView("right_container").setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
new AlertDialog.Builder(mContext)
.setTitle("Foodvite")
.setMessage("Do you want to delete a message?")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SendBird.deleteMessage(((Message) item).getMessageId(), new DeleteMessageHandler() {
#Override
public void onError(SendBirdException e) {
e.printStackTrace();
}
#Override
public void onSuccess(long messageId) {
mSendBirdMessagingAdapter.delete(item);
mSendBirdMessagingAdapter.notifyDataSetChanged();
Toast.makeText(mContext, "Message has been deleted.", Toast.LENGTH_SHORT).show();
}
});
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.create()
.show();
return true;
}
});
} else {
viewHolder.getView("left_container", View.class).setVisibility(View.VISIBLE);
viewHolder.getView("right_container", View.class).setVisibility(View.GONE);
displayUrlImage(viewHolder.getView("left_thumbnail", CircularImageView.class), message.getSenderImageUrl(), true);
viewHolder.getView("left_name", TextView.class).setText(message.getSenderName());
viewHolder.getView("left_message", TextView.class).setText(message.getMessage());
viewHolder.getView("left_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp()));
if(isGroupChat)
viewHolder.getView("left_name", TextView.class).setVisibility(View.VISIBLE);
else
viewHolder.getView("left_name", TextView.class).setVisibility(View.GONE);
}
break;
case TYPE_SYSTEM_MESSAGE:
SystemMessage systemMessage = (SystemMessage) item;
viewHolder.getView("message", TextView.class).setText(Html.fromHtml(systemMessage.getMessage()));
break;
case TYPE_BROADCAST_MESSAGE:
BroadcastMessage broadcastMessage = (BroadcastMessage) item;
viewHolder.getView("message", TextView.class).setText(Html.fromHtml(broadcastMessage.getMessage()));
break;
case TYPE_FILELINK:
FileLink fileLink = (FileLink) item;
if (fileLink.getSenderId().equals(SendBird.getUserId())) {
viewHolder.getView("left_container", View.class).setVisibility(View.GONE);
viewHolder.getView("right_container", View.class).setVisibility(View.VISIBLE);
displayUrlImage(viewHolder.getView("right_thumbnail", ImageView.class), fileLink.getSenderImageUrl(), true);
viewHolder.getView("right_name", TextView.class).setText(fileLink.getSenderName());
if (fileLink.getFileInfo().getType().toLowerCase().startsWith("image")) {
displayUrlImage(viewHolder.getView("right_image", ImageView.class), fileLink.getFileInfo().getUrl());
} else {
viewHolder.getView("right_image", CircularImageView.class).setImageResource(R.drawable.sendbird_icon_file);
}
viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, fileLink.getTimestamp()));
int readCount = 0;
for (String key : mReadStatus.keySet()) {
if (key.equals(fileLink.getSenderId())) {
continue;
}
if (mReadStatus.get(key) < fileLink.getTimestamp()) {
readCount += 1;
}
}
if (readCount < mReadStatus.size() - 1) {
viewHolder.getView("right_status", TextView.class).setText("Unread");
} else {
viewHolder.getView("right_status", TextView.class).setText("");
}
} else {
viewHolder.getView("left_container", View.class).setVisibility(View.VISIBLE);
viewHolder.getView("right_container", View.class).setVisibility(View.GONE);
displayUrlImage(viewHolder.getView("left_thumbnail", ImageView.class), fileLink.getSenderImageUrl(), true);
viewHolder.getView("left_name", TextView.class).setText(fileLink.getSenderName());
if (fileLink.getFileInfo().getType().toLowerCase().startsWith("image")) {
displayUrlImage(viewHolder.getView("left_image", ImageView.class), fileLink.getFileInfo().getUrl());
} else {
viewHolder.getView("left_image", CircularImageView.class).setImageResource(R.drawable.sendbird_icon_file);
}
if(isGroupChat)
viewHolder.getView("left_name", TextView.class).setVisibility(View.VISIBLE);
else
viewHolder.getView("left_name", TextView.class).setVisibility(View.GONE);
viewHolder.getView("left_time", TextView.class).setText(getDisplayDateTime(mContext, fileLink.getTimestamp()));
}
break;
case TYPE_TYPING_INDICATOR: {
int itemCount = ((List) item).size();
String typeMsg = ((List) item).get(0)
+ ((itemCount > 1) ? " +" + (itemCount - 1) : "")
+ ((itemCount > 1) ? " are " : " is ")
+ "typing...";
viewHolder.getView("message", TextView.class).setText(typeMsg);
break;
}
}
return convertView;
}
public boolean checkTypeStatus() {
/**
* Clear an old type status.
*/
for (String key : mTypeStatus.keySet()) {
Long ts = mTypeStatus.get(key);
if (System.currentTimeMillis() - ts > 10 * 1000L) {
mTypeStatus.remove(key);
return true;
}
}
return false;
}
private class ViewHolder {
private Hashtable<String, View> holder = new Hashtable<String, View>();
private int type;
public int getViewType() {
return this.type;
}
public void setViewType(int type) {
this.type = type;
}
public void setView(String k, View v) {
holder.put(k, v);
}
public View getView(String k) {
return holder.get(k);
}
public <T> T getView(String k, Class<T> type) {
return type.cast(getView(k));
}
}
}
private static String getDisplayDateTime(Context context, long milli) {
Date date = new Date(milli);
if (System.currentTimeMillis() - milli < 60 * 60 * 24 * 1000l) {
return DateFormat.getTimeFormat(context).format(date);
}
return DateFormat.getDateFormat(context).format(date) + " " + DateFormat.getTimeFormat(context).format(date);
}
Try below code for your method,
private static String getDisplayDateTime(Context context, long milli, long milli2)
{
Date date = new Date(milli);
Date previousDate = new Date(milli2);
String strCurrentDate = "", strPreviousDate = "";
if (System.currentTimeMillis() - milli < 60 * 60 * 24 * 1000l)
{
strCurrentDate = DateFormat.getTimeFormat(context).format(date);
if(milli2 != -1)
strPreviousDate = DateFormat.getTimeFormat(context).format(previousDate);
//return strCurrentDate.equals(strPreviousDate) ? "" : strCurrentDate;
}
else
{
strCurrentDate = DateFormat.getDateFormat(context).format(date) + " " + DateFormat.getTimeFormat(context).format(date);
if(milli2 != -1)
strPreviousDate = DateFormat.getDateFormat(context).format(strPreviousDate) + " " + DateFormat.getTimeFormat(context).format(strPreviousDate);
}
return strCurrentDate.equals(strPreviousDate) ? "" : strCurrentDate;
}
Now call your methods like below
if(position > 0)
{
final Object previousItem = getItem(position - 1);
Message previousMessage = (Message) previousItem;
viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp(), previousMessage.getTimestamp()));
}
else
{
viewHolder.getView("right_time", TextView.class).setText(getDisplayDateTime(mContext, message.getTimestamp(), -1));
}
I had a similar problem (ref this SO Question) few months ago and nothing worked except extending from ArrayAdapter<MyObject> instead of BaseAdapter.
So, change the base class of your adapter to ArrayAdapter<MyObject> and implement the prompted method of the abstract class. you might need to move some you your existing code to these overridden methods for better performance.
You can force the system to redraw all items by calling BaseAdapter.notifyDataSetChanged()

Highlight effect while pressing item in custom ListView adapter

There's a system visual effect everytime you click a view in Android. In Lollipop it's the ripple effect. When I created a ListView and associated it to an ordinary ArrayAdapter, this effect was present. Now that I've added a custom ListView, this effect is lost.
Now, I've tried to isolate what the problem is, and since using the same list item layout with a default adapter worked nicely, I would say that the problem is on my custom adapter.
I've seen many solutions related to this case that just implemented the ripple effect calling some drawables; this is not what I'm trying to do. The ripple effect shows only because I'm running the app on Android 5, now what I want to do is to have the default system highlight effect for my items when they're being clicked.
Here are the (hopefully) related pieces of my custom adapter:
public class CustomCardSetsAdapter extends BaseAdapter {
List<Card> totalList;
ArrayList<Boolean> hiddenItems;
ListView parentLV;
Integer curPosition = -1;
public static int selectedRowIndex;
public CustomCardSetsAdapter(CardSets cardList, ListView parentListView)
{
this.parentLV = parentListView;
assignSetValues(cardList);
totalList = cardList.getBlackrockMountain();
totalList.addAll(cardList.getClassic());
totalList.addAll(cardList.getCurseofNaxxramas());
totalList.addAll(cardList.getGoblinsvsGnomes());
Collections.sort(totalList,
new Comparator<Card>() {
public int compare(Card f1, Card f2) {
return f1.toString().compareTo(f2.toString());
}
});
hiddenItems = new ArrayList<>();
for (int i = 0; i < totalList.size(); i++) {
if(!totalList.get(i).getCollectible())
hiddenItems.add(true);
else
hiddenItems.add(false);
}
}
#Override
public int getCount() {
return (totalList.size() - getHiddenCount());
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
final int index = getRealPosition(position);
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.card_list_item, parentLV, false);
}
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Integer prevPosition = curPosition;
curPosition = position;
if(prevPosition >= parentLV.getFirstVisiblePosition() &&
prevPosition <= parentLV.getLastVisiblePosition())
{
View view = parentLV.getChildAt(prevPosition- parentLV.getFirstVisiblePosition());
parentLV.getAdapter().getView(prevPosition,view, parentLV);
}
v.setBackgroundColor(Color.WHITE);
}
});
Card curCard = totalList.get(index);
TextView cardName = (TextView) convertView.findViewById(R.id.cardName);
cardName.setText(curCard.getName());
setRarityColor(curCard,cardName);
TextView manaCost = (TextView) convertView.findViewById(R.id.manaCost);
manaCost.setText((curCard.getCost()).toString());
ImageView setIcon = (ImageView) convertView.findViewById(R.id.setIcon);
setSetIcon(curCard,setIcon);
if(position == curPosition)
convertView.setBackgroundColor(Color.WHITE);
else
convertView.setBackgroundColor(Color.TRANSPARENT);
return convertView;
}
#Override
public int getItemViewType(int position) {
return R.layout.card_list_item;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public boolean isEmpty() {
return false;
}
private int getHiddenCount()
{
int count = 0;
for(int i = 0;i <totalList.size();i++)
if(hiddenItems.get(i))
count++;
return count;
}
private int getRealPosition(int position) {
int hElements = getHiddenCountUpTo(position);
int diff = 0;
for(int i=0;i<hElements;i++) {
diff++;
if(hiddenItems.get(position+diff))
i--;
}
return (position + diff);
}
private int getHiddenCountUpTo(int location) {
int count = 0;
for(int i=0;i<=location;i++) {
if(hiddenItems.get(i))
count++;
}
return count;
}
}
Thanks in advance.
in your ListView XML, add:
android:drawSelectorOnTop="true"
I also think you are using your adapter wrong...
Use the ViewHolder Pattern on your Adapter:
public class CustomCardSetsAdapter extends BaseAdapter {
List<Card> totalList;
ArrayList<Boolean> hiddenItems;
ListView parentLV;
Integer curPosition = -1;
public static int selectedRowIndex;
private class ViewHolderRow{
TextView cardName;
TextView manaCost;
ImageView setIcon;
}
public CustomCardSetsAdapter(CardSets cardList, ListView parentListView)
{
this.parentLV = parentListView;
assignSetValues(cardList);
totalList = cardList.getBlackrockMountain();
totalList.addAll(cardList.getClassic());
totalList.addAll(cardList.getCurseofNaxxramas());
totalList.addAll(cardList.getGoblinsvsGnomes());
Collections.sort(totalList,
new Comparator<Card>() {
public int compare(Card f1, Card f2) {
return f1.toString().compareTo(f2.toString());
}
});
hiddenItems = new ArrayList<>();
for (int i = 0; i < totalList.size(); i++) {
if(!totalList.get(i).getCollectible())
hiddenItems.add(true);
else
hiddenItems.add(false);
}
}
#Override
public int getCount() {
return (totalList.size() - getHiddenCount());
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
final int index = getRealPosition(position);
ViewHolderRow theRow;
if(convertView == null) {
theRow = new ViewHolderRow();
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.card_list_item, parentLV, false);
// Cache your views
theRow.cardName = (TextView) convertView.findViewById(R.id.cardName);
theRow.manaCost = (TextView) convertView.findViewById(R.id.manaCost);
theRow.setIcon = (ImageView) convertView.findViewById(R.id.setIcon);
// Set the Tag to the ViewHolderRow
convertView.setTag(theRow);
}else{
// get the Row to re-use
theRow = (ViewHolderRow) convertView.getTag();
}
//... Removed convertView.setOnClickListener
Card curCard = totalList.get(index);
// Set Items
theRow.cardName.setText(curCard.getName());
setRarityColor(curCard,theRow.cardName);
theRow.manaCost.setText((curCard.getCost()).toString());
setSetIcon(curCard,theRow.setIcon);
if(position == curPosition){
convertView.setBackgroundColor(Color.WHITE);
}else{
convertView.setBackgroundColor(Color.TRANSPARENT);
}
return convertView;
}
#Override
public int getItemViewType(int position) {
return R.layout.card_list_item;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public boolean isEmpty() {
return false;
}
private int getHiddenCount()
{
int count = 0;
for(int i = 0;i <totalList.size();i++)
if(hiddenItems.get(i))
count++;
return count;
}
private int getRealPosition(int position) {
int hElements = getHiddenCountUpTo(position);
int diff = 0;
for(int i=0;i<hElements;i++) {
diff++;
if(hiddenItems.get(position+diff))
i--;
}
return (position + diff);
}
private int getHiddenCountUpTo(int location) {
int count = 0;
for(int i=0;i<=location;i++) {
if(hiddenItems.get(i))
count++;
}
return count;
}
}
Set an onListItemClickListener instead of using this on the entire convertView...
yourListView.setOnItemClickListener(ListListener);
private final OnItemClickListener ListListener = new OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
// ... Do something on click
}
}

Android AlphabetIndexer English and Hebrew(Unicode) togather

Following is my listview adapter classes using AlphabetIndexer.
It does not work when I add unicode chars (for hebrew) togather with the english.
I get exception in: getSectionForPosition. getting to index -1....
Tries it with 2 entries in the DB - 1 starting with hebrew char (unicode) and one with english. The first char for AlphabetIndexer was the unicode char.
Really really need help in this one....
public abstract class RecipeListViewAdapter extends SimpleCursorAdapter implements SectionIndexer
{
protected Context mContext;
protected Cursor mCursor;
private LayoutInflater mInflater;
public static final int TYPE_HEADER = 1;
public static final int TYPE_NORMAL = 0;
private static final int TYPE_COUNT = 2;
private AlphabetIndexer indexer;
private int[] usedSectionNumbers;
private Map<Integer, Integer> sectionToOffset;
private Map<Integer, Integer> sectionToPosition;
protected ImageLoader mImageLoader = new ImageLoader( MyApp.Instance() );
public RecipeListViewAdapter( Context context,
int layout,
Cursor c,
String[] from,
int[] to )
{
super(context, layout, c, from, to);
mContext = context;
mCursor = c;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
indexer = new AlphabetIndexer(c, c.getColumnIndexOrThrow("NAME"), "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
sectionToPosition = new TreeMap<Integer, Integer>();
sectionToOffset = new HashMap<Integer, Integer>();
final int count = super.getCount();
int i;
for( i = count - 1 ; i >= 0; i-- )
{
sectionToPosition.put(indexer.getSectionForPosition(i), i);
}
i = 0;
usedSectionNumbers = new int[sectionToPosition.keySet().size()];
for( Integer section : sectionToPosition.keySet() )
{
sectionToOffset.put(section, i);
usedSectionNumbers[i] = section;
i++;
}
for(Integer section: sectionToPosition.keySet())
{
sectionToPosition.put(section, sectionToPosition.get(section) + sectionToOffset.get(section));
}
}
#Override
public int getCount()
{
if( super.getCount() != 0 )
{
return super.getCount() + usedSectionNumbers.length;
}
return 0;
}
#Override
public Object getItem(int position)
{
if (getItemViewType(position) == TYPE_NORMAL) //we define this function later
{
return super.getItem( GetItemPosition( position ) );
}
return null;
}
public int GetItemPosition( final int position )
{
return position - sectionToOffset.get(getSectionForPosition(position)) - 1;
}
public int getPositionForSection(int section) {
if (! sectionToOffset.containsKey(section)){
int i = 0;
int maxLength = usedSectionNumbers.length;
while (i < maxLength && section > usedSectionNumbers[i]){
i++;
}
if (i == maxLength) return getCount();
return indexer.getPositionForSection(usedSectionNumbers[i]) + sectionToOffset.get(usedSectionNumbers[i]);
}
return indexer.getPositionForSection(section) + sectionToOffset.get(section);
}
public int getSectionForPosition(int position) {
int i = 0;
int maxLength = usedSectionNumbers.length;
while (i < maxLength && position >= sectionToPosition.get(usedSectionNumbers[i])){
i++;
}
return usedSectionNumbers[i-1];
}
public Object[] getSections() {
return indexer.getSections();
}
//nothing much to this: headers have positions that the sectionIndexer manages.
#Override
public int getItemViewType(int position) {
if (position == getPositionForSection(getSectionForPosition(position))){
return TYPE_HEADER;
} return TYPE_NORMAL;
}
#Override
public int getViewTypeCount() {
return TYPE_COUNT;
}
#Override
public View getView( int position,
View convertView,
ViewGroup parent )
{
final int type = getItemViewType(position);
if (type == TYPE_HEADER)
{
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.header, parent, false);
}
((TextView)convertView.findViewById(R.id.header)).setText((String)getSections()[getSectionForPosition(position)]);
return convertView;
}
else
{
ViewHolder holder = new ViewHolder();
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.recipes_list_view_entry, null);
holder.name = (TextView) convertView.findViewById( R.id.name_entry );
holder.author = (TextView) convertView.findViewById( R.id.username_entry );
holder.ratingBar = (RatingBar) convertView.findViewById( R.id.list_RatingBarId );
holder.userRatingBar = (RatingBar) convertView.findViewById( R.id.list_userRatingBarId );
holder.diffculty = (ImageView) convertView.findViewById( R.id.list_DifficultyImageViewId );
holder.preparationTime = (ImageView) convertView.findViewById( R.id.list_TimeImageViewId );
holder.recipePic = new DisplayableImageView( (ImageView) convertView.findViewById( R.id.list_RecipeImageViewId ) );
holder.name.setTypeface( MyApp.Fonts.ARIAL );
holder.name.setTextSize( MyApp.Fonts.RUNNING_TEXT_SIZE );
holder.name.setTextColor( Color.BLACK );
}
else
{
holder = (ViewHolder) convertView.getTag();
}
if( super.getItem( GetItemPosition(position) ) != null )
{
// Check if single
if( getCount() == position+1 && position == 1 )
{
convertView.setBackgroundResource( R.drawable.list_single );
}
else if( getItemViewType(position-1) == TYPE_HEADER )
{
// Check if single item in the middle of the list
if( getItemViewType(position+1) == TYPE_HEADER )
{
convertView.setBackgroundResource( R.drawable.list_single );
}
else if( position == getCount() - 1 )
{
convertView.setBackgroundResource( R.drawable.list_single );
}
else
{
convertView.setBackgroundResource( R.drawable.list_up );
}
}
else
{
// Middle or bottom
convertView.setBackgroundResource( R.drawable.list_middle );
//If not last
if( getCount() != position + 1 )
{
// Check if middle or down
if( getItemViewType(position+1) == TYPE_HEADER )
{
convertView.setBackgroundResource( R.drawable.list_down );
}
else
{
convertView.setBackgroundResource( R.drawable.list_middle );
}
}
else
{
// If it is last - use list_down
convertView.setBackgroundResource( R.drawable.list_down );
}
}
FillRecipeDataToHolder( GetItemPosition(position), holder );
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
return convertView;
}
}
//these two methods just disable the headers
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
if (getItemViewType(position) == TYPE_HEADER){
return false;
}
return true;
}
protected abstract void FillRecipeDataToHolder(int position, ViewHolder holder);
static class ViewHolder
{
TextView separator;
DisplayableImageView recipePic;
TextView name;
TextView author;
RatingBar ratingBar;
RatingBar userRatingBar;
ImageView diffculty;
ImageView preparationTime;
TextView serveCount;
}
}

Categories

Resources