Please tell me what I'm doing wrong? I adapter receives data from the server and places them in the foliage. Then, when new data arrive, I try to update the adapter ... and as if all is well, but when it comes .. the new data, eg 2 messages, they are added to the adapter. But with the new data are added to all the other old dannye..Hotya logs on can see that the old data received I do not have a server. It turns out that it is not doing data.clear (). I carry ... data.clear (), my foliage becomes completely empty until the next request Handler.postDelayed () ;. Again request - full foliage and the new data ... 5 seconds passed and my clean sheet again ... and so constantly. How to overcome it?
My Adapter:
public class ChatMsgAdapter extends ArrayAdapter<ResponseMsgArray> {
private Context context;
private ArrayList<ResponseMsgArray> data;
protected String LV_KEY = Auth.key;
protected int LV_USID = Integer.parseInt(Auth.id);
protected int GET_ID = Integer.parseInt(FriendActivity.get_id);
String LOG_TAG = "FriendLOG";
public ChatMsgAdapter(Context context, ArrayList<ResponseMsgArray> values) {
super(context,R.layout.activity_friend_msg, values);
this.data = values;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v;
int type = getItemViewType(position);
if(type == LV_USID) {
v = inflater.inflate(R.layout.activity_friend_msg_adapter, null);
TextView user_id_msg = (TextView) v.findViewById(R.id.id_msg);
TextView user_text = (TextView) v.findViewById(R.id.msg);
TextView user_date = (TextView) v.findViewById(R.id.msg_time);
user_text.setText(data.get(position).getMsg());
user_date.setText(data.get(position).getMsg_time());
user_id_msg.setText(data.get(position).getMsg_id());
} else if (type == GET_ID) {
v = inflater.inflate(R.layout.talker, null);
TextView talker_text = (TextView) v.findViewById(R.id.msg);
TextView talker_date = (TextView) v.findViewById(R.id.msg_time);
talker_text.setText(data.get(position).getMsg());
talker_date.setText(data.get(position).getMsg_time());
} else {
//Если нет например сообщений
v = inflater.inflate(R.layout.msg_null, null);
}
return v;
}
public void setData(ArrayList<ResponseMsgArray> newData) {
addAll(newData);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
int newPosition = Integer.parseInt(data.get(position).getMsg_id_us());
return newPosition;
}
}
Text translated with the help of an interpreter. Thank you for understanding.
Here in this post https://ru.stackoverflow.com/questions/579311/%d0%9f%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%87%d0%b0-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%b2-%d0%b4%d1%80%d1%83%d0%b3%d0%be%d0%b9-%d0%ba%d0%bb%d0%b0%d1%81%d1%81/579403?noredirect=1#comment769066_579403 are all my current classes
Related
Im new in realm db. I completed add and get data in realm db. But, I couldn't sort(ascending and descending).Im my code it display items in listview. Listview contains 5 list and each list contains 4 field(name, age, skill and date). if I sort(ascending) name, need to ascending in 5 list.My code is not work
I post my code here,
private void Ascending_order() {
realm.beginTransaction();
RealmResults<Employee> result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
realm.copyFromRealm(result);
realm.commitTransaction();
employeedetailadapter.notifyDataSetChanged();
}
Adapter class:
public class EmployeeDetailAdapter extends BaseAdapter {
private ArrayList<Employee>employeeDetaillists = new ArrayList<>();
private Context c;
private LayoutInflater inflater;
private OnItemClick mCallback;
private SimpleDateFormat df = new SimpleDateFormat("dd/mm/yyyy");
public EmployeeDetailAdapter(Context c,ArrayList<Employee> employeeDetaillists, OnItemClick listener) {
this.employeeDetaillists = employeeDetaillists;
this.c= c;
inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mCallback = listener;
}
#Override
public int getCount() {
return employeeDetaillists.size();
}
#Override
public Object getItem(int position) {
return employeeDetaillists.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
Holder holder;
if (v==null){
v= (View) inflater.inflate(R.layout.list_single_item,null);
holder = new Holder();
holder.tvPersonName = (TextView) v.findViewById(R.id.tvPersonName);
holder.tvPersonAge = (TextView) v.findViewById(R.id.tvPersonAge);
holder.tvPersonSkill = (TextView) v.findViewById(R.id.tvPersonSkill);
holder.ivEditPesonDetail=(ImageView)v.findViewById(R.id.ivEditPesonDetail);
holder.tvPersondate=(TextView)v.findViewById(R.id.tvPersondate);
holder.ivDeletePerson=(ImageView)v.findViewById(R.id.ivDeletePerson);
v.setTag(holder);
}else{
holder = (Holder) v.getTag();
}
holder.tvPersonName.setText(employeeDetaillists.get(position).getName());
holder.tvPersonAge.setText(employeeDetaillists.get(position).getAge());
holder.tvPersonSkill.setText(employeeDetaillists.get(position).getSkill());
String strDate = df.format(employeeDetaillists.get(position).getSdate());
holder.tvPersondate.setText(strDate);
holder.ivDeletePerson.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Delete(employeeDetaillists.get(position).getName(),position);
}
});
return v;
}
private void Delete(String name, int position) {
mCallback.onClickdelete(name, position);
}
public void updateData(RealmResults<Employee> result) {
}
class Holder {
TextView tvPersonName, tvPersonAge, tvPersonSkill,tvPersondate;
ImageView ivDeletePerson, ivEditPesonDetail;
}
}
Your code does't change db. You just get sorted items but don't use them.
realm.copyFromRealm(result); // this line does nothing
realm.commitTransaction(); // this one too, because you change nothing
employeedetailadapter.notifyDataSetChanged(); // you data is the same, so this line also useless here
To see your data sorted you should use RealmResults in your adapter. With this approach your list always will sorted, even after adding new items. But note: your adapter should extends RealmRecyclerViewAdapter.
You should run this code before creating adapter and use result inside adapter:
RealmResults<Employee> result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
Also you can try manually update data of your adapter.
private void Ascending_order() {
RealmResults<Employee> result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
employeedetailadapter.updateData(result); // update data inside adapter before calling `notifyDataSetChanged`
employeedetailadapter.notifyDataSetChanged();
}
You need to create updateData method yourself:
public void updateData(RealmResults<Employee> result) {
employeeDetaillists = new ArrayList<Employee>(result);
}
First of all, while getting data from Realm you don't need to write it in Transaction. Write Transaction is required only when you are adding data in realm or updating any realm object.
And about your problem, To get sorted data from realm, You can do it like this
RealmResults<Employee> result = realm.where(Employee.class).sort("name", Sort.ASCENDING).findAll();
Now the data you got is sorted, If you still see wrong order in your ListView then there could be some issue in your Adapter. If you share your adapter code, then I can help further :)
Updated:
Adapter Class
public class EmployeeDetailAdapter extends BaseAdapter {
private RealmResults<Employee> employeeDetaillists;
private Context c;
private LayoutInflater inflater;
private OnItemClick mCallback;
private SimpleDateFormat df = new SimpleDateFormat("dd/mm/yyyy");
public EmployeeDetailAdapter(Context c,RealmResults<Employee> employeeDetaillists, OnItemClick listener) {
this.employeeDetaillists = employeeDetaillists;
this.c= c;
inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mCallback = listener;
}
#Override
public int getCount() {
return employeeDetaillists.size();
}
#Override
public Object getItem(int position) {
return employeeDetaillists.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
Holder holder;
if (v==null){
v= (View) inflater.inflate(R.layout.list_single_item,null);
holder = new Holder();
holder.tvPersonName = (TextView) v.findViewById(R.id.tvPersonName);
holder.tvPersonAge = (TextView) v.findViewById(R.id.tvPersonAge);
holder.tvPersonSkill = (TextView) v.findViewById(R.id.tvPersonSkill);
holder.ivEditPesonDetail=(ImageView)v.findViewById(R.id.ivEditPesonDetail);
holder.tvPersondate=(TextView)v.findViewById(R.id.tvPersondate);
holder.ivDeletePerson=(ImageView)v.findViewById(R.id.ivDeletePerson);
v.setTag(holder);
}else{
holder = (Holder) v.getTag();
}
holder.tvPersonName.setText(employeeDetaillists.get(position).getName());
holder.tvPersonAge.setText(employeeDetaillists.get(position).getAge());
holder.tvPersonSkill.setText(employeeDetaillists.get(position).getSkill());
String strDate = df.format(employeeDetaillists.get(position).getSdate());
holder.tvPersondate.setText(strDate);
holder.ivDeletePerson.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Delete(employeeDetaillists.get(position).getName(),position);
}
});
return v;
}
private void Delete(String name, int position) {
mCallback.onClickdelete(name, position);
}
public void updateData(RealmResults<Employee> result) {
}
class Holder {
TextView tvPersonName, tvPersonAge, tvPersonSkill,tvPersondate;
ImageView ivDeletePerson, ivEditPesonDetail;
}
}
In your Activity please change following function
private void Ascending_order() {
result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
employeedetailadapter.notifyDataSetChanged();
}
"result" list should be declared on class level and should be passed to Adapter's constructor as well.
Like
class Activity {
RealmResults<Employee> result;
EmployeeDetailAdapter employeedetailadapter;
//// Other Code
public onCreate(Bundle b) {
result = realm.where(Employee.class).findAll();
employeedetailadapter = new EmployeeDetailAdapter(this, result, listener);
// Other code
}
}
Am trying to update my listview on every selection of the spinner. but its not working. Instead of getting new data, listview is repeating the same values.
I am unable to find out what is my mistake.
here is my avtivity code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
setContentView(R.layout.activity_performance_details);
PerfList = new ArrayList<PerformanceListItem>();
months = (Spinner) findViewById(R.id.load_month);
listview_performance = (ListView) findViewById(R.id.performance_details_list);
sadapter = new PerformanceAdapter(PerformanceDetails.this, PerfList);
months.setOnItemSelectedListener(this);
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Spinner a=(Spinner)parent;
if(a.getId() == R.id.load_month) {
monthid =1+(int)months.getSelectedItemPosition();
Toast.makeText(getApplicationContext(),""+monthid,Toast.LENGTH_LONG).show();
new setAsyncTask_performance().execute();
}
}
after selecting spinner data it is sent to server and from server its relevant data is fetched and sent back to the list view. now when i first time select the spinner it show the data accordingly. But on second selection it will include the previous data without updating the listview
Adapter Code:
public class PerformanceAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private Context context;
private List<PerformanceListItem> performanceList;
public PerformanceAdapter(Activity activity, List<PerformanceListItem> PList) {
this.activity = activity;
this.performanceList = PList;
}
#Override
public int getCount() {
return performanceList.size();
}
#Override
public Object getItem(int position) {
return performanceList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null) {
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.performance_itemlist, null);
}
Animation slideUp = AnimationUtils.loadAnimation(activity, R.anim.slide_up);
TextView staffName = (TextView) convertView.findViewById(R.id.perf_staffName);
TextView staffDesignation = (TextView) convertView.findViewById(R.id.perf_Design);
TextView staffPerformance = (TextView) convertView.findViewById(R.id.perf_performance);
PerformanceListItem plist = performanceList.get(position);
staffName.setText(plist.getpStaffName());
staffDesignation.setText(plist.getpDesignation());
staffPerformance.setText(plist.getpPerformance());
slideUp.setDuration(500);
convertView.startAnimation(slideUp);
slideUp = null;
return convertView;
}
}
and this is my performance list to get and set data
PerformanceListItems code:
public class PerformanceListItem {
private String pSid;
private String pStaffName;
private String pDesignation;
private String pPerformance;
private String pList;
public PerformanceListItem(){
}
public PerformanceListItem(String pList){
this.pList = pList;
}
public String getpSid(){
return pSid;
}
public void setpSid(String pSid){
this.pSid = pSid;
}
public String getpStaffName(){
return pStaffName;
}
public void setpStaffName(String pStaffName){
this.pStaffName = pStaffName;
}
public String getpDesignation(){
return pDesignation;
}
public void setpDesignation(String pDesignation){
this.pDesignation = pDesignation;
}
public String getpPerformance(){
return pPerformance;
}
public void setpPerformance(String pPerformance){
this.pPerformance = pPerformance;
}
}
After debugging the entire code i found that my JSONObject is not updating with new value
any help would be appreciable.
Update the data of your adapter when you execute this
new setAsyncTask_performance().execute();
If you want to show only the new data just remove all your listview items then update the data and set the adapter again.
dont set adapter in oncreate. Set your adapter in Asynctask Post execute. and set your array inside doinbackground along with getting data task.
Okey so, since I've not found a consistent way of doing this when I searched, I decided that maybe putting my code for somebody elses eyes to see might help.
I'm creating a game where you use cards. These cards can either be locked or unlocked depending on different factors. The important thing is, that I want to check the sqlite db whether they are locked, then display different row layouts for the two possible outcomes.
Here's my code:
public class AllCardsAdapter extends CursorAdapter {
LockedHolder viewLocked;
UnlockedHolder viewUnlocked;
private LayoutInflater mInflater;
public static final int LOCKED = 0;
public static final int UNLOCKED = 1;
public AllCardsAdapter(Context context, Cursor cursor) {
super(context, cursor);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
final int type;
int viewType = this.getItemViewType(cursor.getInt(cursor.getColumnIndex("unlocked")));
if (viewType == 1){
type = UNLOCKED;
} else {
type = LOCKED;
}
if (type == LOCKED){
viewLocked = (LockedHolder) view.getTag();
viewLocked.nameHolder.setText(cursor.getString(cursor.getColumnIndex("name")));
viewLocked.awardedAtHolder.setText("Awarded at level:");
viewLocked.reqLvlHolder.setText(cursor.getString(cursor.getColumnIndex("reqlvl")));
String imagePath = cursor.getString(cursor.getColumnIndex("image"));
if (imagePath.equals("card_obj_plus_1")){
Picasso.with(context).load(R.drawable.card_obj_plus_1).placeholder(R.drawable.card_placeholder).into(viewLocked.imageHolder);
}
if (imagePath.equals("card_obj_plus_2")){
Picasso.with(context).load(R.drawable.card_obj_plus_2).placeholder(R.drawable.card_placeholder).into(viewLocked.imageHolder);
}
if (imagePath.equals("card_obj_plus_3")){
Picasso.with(context).load(R.drawable.card_obj_plus_3).placeholder(R.drawable.card_placeholder).into(viewLocked.imageHolder);
}
if (imagePath.equals("card_slowdown")){
Picasso.with(context).load(R.drawable.card_slowdown).placeholder(R.drawable.card_placeholder).into(viewLocked.imageHolder);
}
if (imagePath.equals("card_speed_up")){
Picasso.with(context).load(R.drawable.card_speed_up).placeholder(R.drawable.card_placeholder).into(viewLocked.imageHolder);
}
} else {
viewUnlocked = (UnlockedHolder) view.getTag();
viewUnlocked.nameHolder.setText(cursor.getString(cursor.getColumnIndex("name")));
String imagePath = cursor.getString(cursor.getColumnIndex("image"));
if (imagePath.equals("card_obj_plus_1")){
Picasso.with(context).load(R.drawable.card_obj_plus_1).placeholder(R.drawable.card_placeholder).into(viewUnlocked.imageHolder);
}
if (imagePath.equals("card_obj_plus_2")){
Picasso.with(context).load(R.drawable.card_obj_plus_2).placeholder(R.drawable.card_placeholder).into(viewUnlocked.imageHolder);
}
if (imagePath.equals("card_obj_plus_3")){
Picasso.with(context).load(R.drawable.card_obj_plus_3).placeholder(R.drawable.card_placeholder).into(viewUnlocked.imageHolder);
}
if (imagePath.equals("card_slowdown")){
Picasso.with(context).load(R.drawable.card_slowdown).placeholder(R.drawable.card_placeholder).into(viewUnlocked.imageHolder);
}
if (imagePath.equals("card_speed_up")){
Picasso.with(context).load(R.drawable.card_speed_up).placeholder(R.drawable.card_placeholder).into(viewUnlocked.imageHolder);
}
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
viewLocked = new LockedHolder();
viewUnlocked = new UnlockedHolder();
final int type;
int viewType = this.getItemViewType(cursor.getInt(cursor.getColumnIndex("unlocked")));
if (viewType == 1){
type = UNLOCKED;
} else {
type = LOCKED;
}
System.out.println(viewType);
System.out.println(type);
if (type == LOCKED){
View lockedView;
lockedView = mInflater.inflate(R.layout.card_list_row_disabled, parent, false);
viewLocked.nameHolder = (TextView) lockedView.findViewById(R.id.txtTitle);
viewLocked.imageHolder = (ImageView) lockedView.findViewById(R.id.imgThumbnail);
viewLocked.reqLvlHolder = (TextView) lockedView.findViewById(R.id.tvLevelNr);
viewLocked.awardedAtHolder = (TextView) lockedView.findViewById(R.id.tvAwardedAt);
lockedView.setTag(viewLocked);
return lockedView;
} else {
View unlockedView;
unlockedView = mInflater.inflate(R.layout.card_list_row, parent, false);
viewUnlocked.nameHolder = (TextView) unlockedView.findViewById(R.id.txtTitle);
viewUnlocked.imageHolder = (ImageView) unlockedView.findViewById(R.id.imgThumbnail);
unlockedView.setTag(viewUnlocked);
return unlockedView;
}
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
return position % 2;
}
public class LockedHolder {
public TextView nameHolder;
public ImageView imageHolder;
public TextView awardedAtHolder;
public TextView reqLvlHolder;
}
public class UnlockedHolder {
public TextView nameHolder;
public ImageView imageHolder;
}
}
The error I'm getting is on the row "viewLocked = (LockedHolder) view.getTag();"
AllCardsAdapter$UnlockedHolder cannot be cast to AllCardsAdapter$LockedHolder
The error only shows up when I have a list containing cards that are both locked and unlocked.
See I know what it's trying to do, I just don't know why. Also, if I'm overcomplicating things for no good reason, or missing something obvious, I'd be much appreciated if you find it..
getItemViewType implementation does not look right (type does not depend on item position) it should be something like the following
private int getItemViewType(Cursor cursor) {
return cursor.getInt(cursor.getColumnIndex("unlocked")) % 2;
}
#Override
public int getItemViewType(int position) {
Cursor cursor = (Cursor) getItem(position);
return getItemViewType(cursor);
}
You also need to update bindView and newView
int viewType = this.getItemViewType(cursor);
I would like to ask some question about AdapterView.
In my application, there is an activity which retrieve data from database and display them in AdapterView.
However, when i install the application in different devices, I found that the part I have just mentioned could only function on some devices. The others cannot show the database results.
Here is my code:
private void showResults(String query) {
Cursor cursor = searchCustByInputText(query);
if (cursor == null) {
//
} else {
// Specify the columns we want to display in the result
String[] from = new String[] {
"cust_code",
"chinese_name"};
// Specify the Corresponding layout elements where we want the columns to go
int[] to = new int[] {
R.id.scust_code,
R.id.schinese_name};
// Create a simple cursor adapter for the definitions and apply them to the ListView
SimpleCursorAdapter customers = new SimpleCursorAdapter(this,R.layout.cust_list_item, cursor, from, to);
mListView.setAdapter(customers);
// Define the on-click listener for the list items
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor c = (Cursor) mListView.getItemAtPosition(position);
String cust_code = c.getString(c.getColumnIndex("cust_code"));
if (callFromAct.equals("Main")) {
String pay_term = c.getString(c.getColumnIndex("pay_term"));
String chinese_name = c.getString(c.getColumnIndex("chinese_name"));
String english_name = c.getString(c.getColumnIndex("english_name"));
String address_1 = c.getString(c.getColumnIndex("address_1"));
String address_2 = c.getString(c.getColumnIndex("address_2"));
String address_3 = c.getString(c.getColumnIndex("address_3"));
String address_4 = c.getString(c.getColumnIndex("address_4"));
String contact = c.getString(c.getColumnIndex("contact"));
String telephone = c.getString(c.getColumnIndex("telephone"));
String last_order_date = c.getString(c.getColumnIndex("last_order_date"));
//Pass data to another Activity
Intent it = new Intent(CustEnqActivity.this, CustEnqDetailsActivity.class);
Bundle bundle = new Bundle();
bundle.putString("cust_code", cust_code);
bundle.putString("pay_term", pay_term);
bundle.putString("chinese_name", chinese_name);
bundle.putString("english_name", english_name);
bundle.putString("address_1", address_1);
bundle.putString("address_2", address_2);
bundle.putString("address_3", address_3);
bundle.putString("address_4", address_4);
bundle.putString("contact", contact);
bundle.putString("telephone", telephone);
bundle.putString("last_order_date", last_order_date);
it.putExtras(bundle);
startActivity(it);
}
else {
returnToCallingAct(cust_code);
}
//searchView.setQuery("",true);
}
});
}
}
Besides, I discovered there were two warnings in my logcat.
The constructor SimpleCursorAdapter(Context, int, Cursor, String[], int[]) is deprecated
AdapterView is a raw type. References to generic type AdapterView should be parameterized
Are they related to the problem?
Try to create a class that extends BaseAdapter and use ViewHolders for performance
eg:
public class MyBaseAdapter extends BaseAdapter {
ArrayList<ListData> myList = new ArrayList<ListData>();
LayoutInflater inflater;
Context context;
public MyBaseAdapter(Context context, ArrayList<ListData> myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context); // only context can also be used
}
#Override
public int getCount() {
return myList.size();
}
#Override
public ListData getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.layout_list_item, null);
mViewHolder = new MyViewHolder();
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
mViewHolder.tvTitle = detail(convertView, R.id.tvTitle, myList.get(position).getTitle());
mViewHolder.tvDesc = detail(convertView, R.id.tvDesc, myList.get(position).getDescription());
mViewHolder.ivIcon = detail(convertView, R.id.ivIcon, myList.get(position).getImgResId());
return convertView;
}
// or you can try better way
private TextView detail(View v, int resId, String text) {
TextView tv = (TextView) v.findViewById(resId);
tv.setText(text);
return tv;
}
private ImageView detail(View v, int resId, int icon) {
ImageView iv = (ImageView) v.findViewById(resId);
iv.setImageResource(icon); //
return iv;
}
private class MyViewHolder {
TextView tvTitle, tvDesc;
ImageView ivIcon;
}
}
More info/example:
http://www.pcsalt.com/android/listview-using-baseadapter-android/#sthash.lNGSCiyB.dpbs
I have custom adapter and I want pick out new messages. My adapter looks like. New messages have new_message icon.
public class InputMessagesAdapter extends BaseAdapter {
private Context context;
private LayoutInflater layoutInflater;
private List<Message> messageList;
private List<SellerStatement> sellerStatementList;
private List<Integer> messagesIds;
private String arrayName = "messagesIds";
private SharedPreferences prefs;
public InputMessagesAdapter(Context context, List<Message> messageList, List<SellerStatement> sellerStatementList) {
this.context = context;
layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.messageList = messageList;
this.sellerStatementList = sellerStatementList;
prefs = PreferenceManager.getDefaultSharedPreferences(context);
int size = prefs.getInt(arrayName + "_size", 0);
Integer[] tempArray = new Integer[size];
for(int i = 0; i < size; i++)
tempArray[i] = prefs.getInt(arrayName + "_" + i, -1);
messagesIds = new ArrayList<Integer>(Arrays.asList(tempArray));
}
#Override
public int getCount() {
return messageList.size();
}
#Override
public Object getItem(int position) {
return messageList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
Message message = messageList.get(position);
View view = convertView;
if (view == null) {
view = layoutInflater.inflate(R.layout.fragment_messages_new_row, null);
}
TextView subject = (TextView) view.findViewById(R.id.tvSubject);
TextView date = (TextView) view.findViewById(R.id.tvDate);
TextView sender = (TextView) view.findViewById(R.id.tvSender);
ImageView icon = (ImageView) view.findViewById(R.id.imMessage);
SellerStatement sellerStatement = sellerStatementList.get(position);
subject.setText(message.getSubject());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
date.setText(String.valueOf(sdf.format(message.getTimestamp())));
sender.setText(sellerStatement.getSender().getGoogleAccount());
Drawable image = context.getResources().getDrawable(R.drawable.old_message);
if(!messagesIds.contains(message.getMessageId()))
image = context.getResources().getDrawable(R.drawable.new_message);
icon.setImageDrawable(image);
return view;
}
}
I try it, but all items change color.
if(!messagesIds.contains(message.getMessageId())) {
image = context.getResources().getDrawable(R.drawable.new_message);
view.setBackgroundColor(COLOR);
}
And this work incorrect too (I change background color for layout)
View view = convertView;
if (view == null) {
if(!messagesIds.contains(message.getMessageId())) {
view = layoutInflater.inflate(R.layout.fragment_messages_new_row, null);
} else {
view = layoutInflater.inflate(R.layout.fragment_messages_row, null);
}
}
How can I solve this task?
It is simple:
View view = convertView; //find this line in your code
view.setBackgroundColor(Color.CYAN); //add this line below
After update the adapter use adapter.notifyDataSetChanged() to force the List to redraw
Add the time you create your adapter and it creates your views, all the message id's are in the list, therefore, !messagesIds.contains(message.getMessageId()) will allways be false.
At the moment you add a new message to the message list, you have to call the notifyDatasetChanged()method on your Adapter. This will create all views again and add your new message with the new icon and background color