Change button in listview with reference to data - sqlite

i can speak english just little..
i made listview with sqlite db.
I want to implement this function
ex)
i have sqlite db (with listview. i made already. and listview have button)
rowId 1, 2, 3
number 0, 1, 0
i need like this
if ( number == 0) {
button.backgroundResource(R.drawble.icon1);
} else if ( number == 1) {
button.backgroundResource(R.drawble.icon2);
}
Attached pictures for easier understanding.
enter image description here
and this is my listadapter
public class ListAdapter extends BaseAdapter implements View.OnClickListener {
public interface ListBtnClickListener {
void onListBtnClick(int position, View view);
}
public ListAdapter(Context mContext, ArrayList<SongList> mList, ListBtnClickListener clickListener) {
this.mContext = mContext;
this.mList = mList;
this.listBtnClickListener = clickListener;
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSelectedItemsIds = new SparseBooleanArray();
}
#Override
public int getCount() {
return mList.size();
}
#Override
public Object getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View view = convertView;
if (view == null) {
viewHolder = new ViewHolder();
view = layoutInflater.inflate(R.layout.list_item, null);
viewHolder.relativeLayout = (RelativeLayout) view.findViewById(R.id.listview_item);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
_url = (TextView) view.findViewById(R.id.song_url);
_name = (TextView) view.findViewById(R.id.song_name);
_time = (TextView) view.findViewById(R.id.song_time);
_img = (ImageView) view.findViewById(R.id.song_thumbnail);
favorite = (Button) view.findViewById(R.id.favorite);
Bitmap bitmap = BitmapFactory.decodeByteArray(mList.get(position).get_img(), 0, mList.get(position).get_img().length);
_img.setImageBitmap(bitmap);
final SongList listViewItem = mList.get(position);
if (mList != null) {
_url.setText(listViewItem.get_url());
_name.setText(listViewItem.get_name());
_time.setText(listViewItem.get_time());
}
final SongList songList = mList.get(position);
favorite.setTag(position);
favorite.setOnClickListener(this);
return view;
}
#Override
public void onClick(View view) {
if (this.listBtnClickListener != null) {
this.listBtnClickListener.onListBtnClick((int) view.getTag(), view);
}
}
public class ViewHolder {
private RelativeLayout relativeLayout = null;
}
}

I assume you have some method like SongList.getNumber(). You can change your code in if block like this:
if (mList != null) {
_url.setText(listViewItem.get_url());
_name.setText(listViewItem.get_name());
_time.setText(listViewItem.get_time());
// assuming you have getNumber() method
int number = listViewItem.getNumber();
// checking if number is equal to 0
if(number == 0){
favorite.backgroundResource(R.drawble.icon1);
} else{
favorite.backgroundResource(R.drawble.icon2);
}
}
Edit: If you are storing number variable for only changing the background of button, then you can just use position parameter provided in getView() method. All you have to do is check if position is even or odd and change the background of the button accordingly.

Related

In 3 level Nested Expand/ Collapse Vertical(all) Recyclerview data is not updated in inner Recyclerviews after 1st or subsequent time Qrcode scan data

After first qr code scan i make API call and get data. its work fine. But later when i scan other QRcode the data is retrieved but its not shown in inner recyclerview, mean no expand and collapse function works.
after instantiating recyclerview, adapter & layout manager. i scan qrcode and with result i make api call. then observe it and send data for first binding.
Below is Observer.
//ViewModel Observer
private void observeVIewModel() {
qrTrac_viewModel.getQRTrackListLiveData().observe(this, qrTrackingList -> {
if (qrTrac_viewModel.getSerResponseCodeVModel() != null) {
if (qrTrac_viewModel.getSerResponseCodeVModel().equals(Constants.OK)){
if (qrTrackingList != null) {
Util.Logd(qrTrackingList.getLstQRL0().toString());
progressActivity.dismiss();
Util.Logd("qrtrack viewmodel call");
mLstQRL0Adapter.setLstQRL0List((ArrayList<LstQRL0>) qrTrackingList.getLstQRL0(),(ArrayList<LstQRL1Info>) qrTrackingList.getLstQRL1Info(),
(ArrayList<LstQRTrackingSummary>) qrTrackingList.getLstQRTrackingSummary());
}
} else if(qrTrac_viewModel.getSerResponseCodeVModel().equals(Constants.INTERNAL_SERVER_ERROR)){
progressActivity.dismiss();
Util.Loge("in not found");
Snackbar snackbar = Snackbar.make(view, "Internal Server Error", BaseTransientBottomBar.LENGTH_INDEFINITE).setAction(android.R.string.ok, view -> {
});
snackbar.show();
}
else {
progressActivity.dismiss();
Snackbar snackbar = Snackbar.make(view, qrTrac_viewModel.getSerVModelResponseMsg(), BaseTransientBottomBar.LENGTH_INDEFINITE).setAction(android.R.string.ok, v -> {});
snackbar.show();
}
}
else {
progressActivity.dismiss();
Snackbar snackbar = Snackbar.make(view, "Some Unknown Error occured", BaseTransientBottomBar.LENGTH_INDEFINITE).setAction(android.R.string.ok, v -> {});
snackbar.show();
}
});
}
Here is first Adapter.
public class LstQRL0Adapter extends RecyclerView.Adapter<LstQRL0Adapter.LstQRL0ViewHolder> {
private Context context;
private List<LstQRL0> listQRL0 = new ArrayList<>();
private List<LstQRL1Info> listQRl1Info = new ArrayList<>();
private List<LstQRTrackingSummary> listQRTracSumm = new ArrayList<>();
private View view;
private LayoutInflater inflater;
private ArrayList<LstQRL1Info> templistQRl1Info = new ArrayList<>();
private int oldL0ClickPosition = -1;
//lstQRLInfo
private RecyclerView mLstQRL1InfoRecView;
private LstQRL1InfoAdapter mLstQRL1InfoAdapter;
private LinearLayoutManager mLst1Manager;
public LstQRL0Adapter(Context context) {
inflater = LayoutInflater.from(context);
this.context = context;
}
public void setLstQRL0List(ArrayList<LstQRL0> list, ArrayList<LstQRL1Info> listQRl1Info, ArrayList<LstQRTrackingSummary> listQRTracSumm) {
this.listQRL0 = list;
this.listQRl1Info = listQRl1Info;
this.listQRTracSumm = listQRTracSumm;
oldL0ClickPosition = -1 ;
notifyDataSetChanged();
#NonNull
#Override
public LstQRL0Adapter.LstQRL0ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
view = inflater.inflate(R.layout.lstqrl0_baseview, parent, false);
return new LstQRL0ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull LstQRL0Adapter.LstQRL0ViewHolder holder, int position) {
LstQRL0 myL0List = listQRL0.get(position);
holder.mSeason.setText(myL0List.getNvGDSeason());
holder.mStyle.setText(myL0List.getStyleBriefDescr().replace("<br/>", "\n"));
holder.mVendor.setText(myL0List.getNvPartnerVendor());
mLstQRL1InfoAdapter = new LstQRL1InfoAdapter(context);
mLstQRL1InfoRecView.setAdapter(mLstQRL1InfoAdapter);
mLstQRL1InfoRecView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
templistQRl1Info.clear();
for (int i = 0; i < listQRl1Info.size(); i++) {
if (listQRl1Info.get(position).getId().equals(listQRl1Info.get(i).getId()) && !listQRl1Info.get(i).getId().isEmpty()) {
Util.Logd(listQRl1Info.get(i).getId() + " is l0 adapter");
templistQRl1Info.add(listQRl1Info.get(i));
}
}
Util.Logd(templistQRl1Info.size() +" is temp l0 size");
mLstQRL1InfoAdapter.setLstQRL1infoList(templistQRl1Info, (ArrayList<LstQRTrackingSummary>) listQRTracSumm);
if (listQRL0.get(position).isL0Expanded()) {
holder.mLstQrL0ImageView.setImageResource(R.drawable.ic_arrow_drop_down);
mLstQRL1InfoRecView.setVisibility(View.VISIBLE);
} else {
holder.mLstQrL0ImageView.setImageResource(R.drawable.ic_arrow_right);
mLstQRL1InfoRecView.setVisibility(View.GONE);
}
view.setOnClickListener(view -> {
if (oldL0ClickPosition >= 0){
if (listQRL0.get(oldL0ClickPosition).isL0Expanded()) {
listQRL0.get(oldL0ClickPosition).setL0Expanded(false);
mLstQRL1InfoRecView.setVisibility(View.GONE);
notifyItemChanged(oldL0ClickPosition);
}
}
if (oldL0ClickPosition == holder.getAdapterPosition()){
oldL0ClickPosition = -1 ;
}else {
oldL0ClickPosition = holder.getAdapterPosition() ;
}
Util.Logd("Old clickc is "+oldL0ClickPosition);
if (oldL0ClickPosition >= 0){
new Handler(Looper.myLooper()).postDelayed(() -> {
listQRL0.get(oldL0ClickPosition).setL0Expanded(!listQRL0.get(oldL0ClickPosition).isL0Expanded());
notifyItemChanged(oldL0ClickPosition);
}, 500);
}
});
}
#Override
public int getItemCount() {
return listQRL0.size();
}
public class LstQRL0ViewHolder extends RecyclerView.ViewHolder {
private TextView mSeason, mStyle, mVendor;
private ImageView mLstQrL0ImageView;
public LstQRL0ViewHolder(#NonNull View itemView) {
super(itemView);
Util.Logd("just check is called");
mSeason = itemView.findViewById(R.id.lstqrl0_season);
mStyle = itemView.findViewById(R.id.lstqrl0_style);
mVendor = itemView.findViewById(R.id.lstqrl0_vendor);
mLstQrL0ImageView = itemView.findViewById(R.id.lstqr10_arrow);
mLstQRL1InfoRecView = itemView.findViewById(R.id.lstqrl1info_rv);
}
}
}
Here is Second Adapter
public class LstQRL1InfoAdapter extends RecyclerView.Adapter<LstQRL1InfoAdapter.LstQRL1InfoViewHolder> {
private Context context;
private List<LstQRL1Info> lstQRL1Infos = new ArrayList<>();
private List<LstQRTrackingSummary> listQRTracSumm = new ArrayList<>();
private ArrayList<LstQRTrackingSummary> tempListQRTracSumm = new ArrayList<>();
private View view;
private LayoutInflater inflater;
private int oldL1ClickPosition = 0; // not used in this case
//LstQRTracingSummary
private RecyclerView mQRLTracSummRV;
private LstQRTracSummAdapter mQrTracSummAdapter;
private LinearLayoutManager mQrTrackSummManager;
public LstQRL1InfoAdapter(Context context) {
this.context = context;
inflater = LayoutInflater.from(context);
}
public void setLstQRL1infoList(ArrayList<LstQRL1Info> list, ArrayList<LstQRTrackingSummary> listQRTracSumm) {
this.lstQRL1Infos = list;
this.listQRTracSumm = listQRTracSumm;
notifyDataSetChanged();
}
#NonNull
#Override
public LstQRL1InfoViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
view = inflater.inflate(R.layout.lstqrl1info_baseview, parent, false);
return new LstQRL1InfoViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull LstQRL1InfoViewHolder holder, int position) {
holder.bind(lstQRL1Infos.get(position),position);
}
#Override
public int getItemCount() {
return lstQRL1Infos.size();
}
public class LstQRL1InfoViewHolder extends RecyclerView.ViewHolder {
private TextView quantity, info, add_info;
private ImageView mlstqrl1info_arrow;
public LstQRL1InfoViewHolder(#NonNull View itemView) {
super(itemView);
quantity = itemView.findViewById(R.id.lstqr1info_quantity);
info = itemView.findViewById(R.id.lstqr1info_info);
add_info = itemView.findViewById(R.id.lstqrl1info_add_info);
mQRLTracSummRV = itemView.findViewById(R.id.lstqrtracsumm_rv);
mlstqrl1info_arrow = itemView.findViewById(R.id.lstqr1info_arrow);
itemView.setOnClickListener(view -> {
if (lstQRL1Infos.get(oldL1ClickPosition).isL1Expanded()) {
Util.Logd("in expanded check");
lstQRL1Infos.get(oldL1ClickPosition).setL1Expanded(false);
mQRLTracSummRV.setVisibility(View.GONE);
notifyItemChanged(oldL1ClickPosition);
}
oldL1ClickPosition = getAdapterPosition() ;
new Handler(Looper.myLooper()).postDelayed(() -> {
}, 500);
lstQRL1Infos.get(getAdapterPosition()).setL1Expanded(!lstQRL1Infos.get(getAdapterPosition()).isL1Expanded());
notifyItemChanged(getAdapterPosition());
});
}
public void bind(LstQRL1Info lstQRL1Info,int position) {
quantity.setText(Math.round(lstQRL1Info.getmQty())+"");
info.setText(lstQRL1Info.getNvGDActivity());
add_info.setText(lstQRL1Info.getNvAdditionalInfo1());
mQrTracSummAdapter = new LstQRTracSummAdapter(context);
mQRLTracSummRV.setAdapter(mQrTracSummAdapter);
mQRLTracSummRV.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
tempListQRTracSumm.clear() ;
for (int i = 0; i < listQRTracSumm.size(); i++) {
if (lstQRL1Info.getId().equals(listQRTracSumm.get(i).getIdQRTrackingList()) && !listQRTracSumm.get(i).getIdQRTrackingList().isEmpty()) {
tempListQRTracSumm.add(listQRTracSumm.get(i));
Util.Logd(listQRTracSumm.get(i).getIdQRTrackingList() + " is info adapter");
}
}
Util.Logd("in view binding and size is " + lstQRL1Infos.size() + " "+ tempListQRTracSumm.size());
mQrTracSummAdapter.setListQRTracSumm(tempListQRTracSumm);
if (lstQRL1Infos.get(position).isL1Expanded()) {
mlstqrl1info_arrow.setImageResource(R.drawable.ic_arrow_drop_down);
mQRLTracSummRV.setVisibility(View.VISIBLE);
} else {
mlstqrl1info_arrow.setImageResource(R.drawable.ic_arrow_right);
mQRLTracSummRV.setVisibility(View.GONE);
}
}
}
}
Third adapter is also same as like second one.
First Adapter is bit different from second and third as am working on it to achieve what is needed.
Probelem : When i scan second and subsequent times then data from api call is received and i think properly set as well but somewhow its not show recyclerview 2 data.(First recyclerview data is shown properly).
Help me whether its different approach or update in same code.
Thanks in Advance.
UPDATE - Above code is correct , the mistake I was doing is -> I was creating RecyclerView adapter instance in advance when Activity runs for 1st time (Which is advance initialization of adapter) and was updating data later when QrCode is scanned and Api call is made .
So now I was creating instance when data is received by observer . as Shown Below
private void observeVIewModel() {
qrTrac_viewModel.getQRTrackListLiveData().observe(this, qrTrackingList -> {
if (qrTrac_viewModel.getSerResponseCodeVModel() != null) {
if (qrTrac_viewModel.getSerResponseCodeVModel().equals(Constants.OK)){
if (qrTrackingList != null) {
Util.Logd(qrTrackingList.getLstQRL0().toString());
progressActivity.dismiss();
Util.Logd("qrtrack viewmodel call");
// result sent to adapters for binding
mLstQRL0Adapter = new LstQRL0Adapter(this,(ArrayList<LstQRL0>) qrTrackingList.getLstQRL0(),(ArrayList<LstQRL1Info>) qrTrackingList.getLstQRL1Info(),
(ArrayList<LstQRTrackingSummary>) qrTrackingList.getLstQRTrackingSummary());
mLst0Manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mLst0RecView.setLayoutManager(mLst0Manager);
mLst0RecView.setNestedScrollingEnabled(false);
mLst0RecView.setRecycledViewPool(sharedPool);
mLst0RecView.setAdapter(mLstQRL0Adapter);
mLstQRL0Adapter.notifyDataSetChanged();
}
} else if(qrTrac_viewModel.getSerResponseCodeVModel().equals(Constants.INTERNAL_SERVER_ERROR)){
progressActivity.dismiss();
Util.Loge("in not found");
Snackbar snackbar = Snackbar.make(view, "Internal Server Error", BaseTransientBottomBar.LENGTH_INDEFINITE).setAction(android.R.string.ok, view -> {
});
snackbar.show();
}
else {
progressActivity.dismiss();
Snackbar snackbar = Snackbar.make(view, qrTrac_viewModel.getSerVModelResponseMsg(), BaseTransientBottomBar.LENGTH_INDEFINITE).setAction(android.R.string.ok, v -> {});
snackbar.show();
}
}
else {
progressActivity.dismiss();
Snackbar snackbar = Snackbar.make(view, "Some Unknown Error occured", BaseTransientBottomBar.LENGTH_INDEFINITE).setAction(android.R.string.ok, v -> {});
snackbar.show();
}
});
}
Same way I was doing for further adapters for nested lists to work better .
1st dapter.
public class LstQRL0Adapter extends RecyclerView.Adapter<LstQRL0Adapter.LstQRL0ViewHolder> {
private Context context;
private List<LstQRL0> listQRL0 = new ArrayList<>() ;
private List<LstQRL1Info> listQRl1Info = new ArrayList<>(); ;
private List<LstQRTrackingSummary> listQRTracSumm = new ArrayList<>();
private View view;
private LayoutInflater inflater;
private ArrayList<LstQRL1Info> templistQRl1Info = new ArrayList<>();
private int oldL0ClickPosition = -1;
private Boolean isFromClose = false ;
//lstQRLInfo
private RecyclerView mLstQRL1InfoRecView;
public LstQRL1InfoAdapter mLstQRL1InfoAdapter;
public LstQRL0Adapter(Context context,ArrayList<LstQRL0> list, ArrayList<LstQRL1Info> listQRl1Info, ArrayList<LstQRTrackingSummary> listQRTracSumm) {
inflater = LayoutInflater.from(context);
this.context = context;
this.listQRL0 = list;
this.listQRl1Info = listQRl1Info;
this.listQRTracSumm = listQRTracSumm;
oldL0ClickPosition = -1;
}
#NonNull
#Override
public LstQRL0Adapter.LstQRL0ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
view = inflater.inflate(R.layout.lstqrl0_baseview, parent, false);
return new LstQRL0ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull LstQRL0Adapter.LstQRL0ViewHolder holder, int position) {
LstQRL0 myL0List = listQRL0.get(position);
holder.mSeason.setText(myL0List.getNvGDSeason());
holder.mStyle.setText(myL0List.getStyleBriefDescr().replace("<br/>", "\n"));
holder.mVendor.setText(myL0List.getNvPartnerVendor());
Util.Logd( "temp l0 size is "+templistQRl1Info.size());
if (!isFromClose){
templistQRl1Info.clear();
if (oldL0ClickPosition >=0){
for (int i = 0; i < listQRl1Info.size(); i++) {
if (listQRL0.get(oldL0ClickPosition).getId().equals(listQRl1Info.get(i).getId())) {
Util.Logd( "temp ids are "+listQRl1Info.get(i).getId());
templistQRl1Info.add(listQRl1Info.get(i));
}
}
}
mLstQRL1InfoAdapter = new LstQRL1InfoAdapter(context,templistQRl1Info, (ArrayList<LstQRTrackingSummary>) listQRTracSumm);
mLstQRL1InfoRecView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
mLstQRL1InfoRecView.setNestedScrollingEnabled(false);
mLstQRL1InfoRecView.setAdapter(mLstQRL1InfoAdapter);
mLstQRL1InfoAdapter.notifyDataSetChanged();
}
boolean isL0Expanded = myL0List.isL0Expanded();
Util.Logd("Expanded status is "+ position + " " + listQRL0.get(position).isL0Expanded());
if (isL0Expanded) {
holder.mLstQrL0ImageView.setImageResource(R.drawable.ic_arrow_drop_down);
holder.hideShowL0Layout.setVisibility(View.VISIBLE);
} else {
holder.mLstQrL0ImageView.setImageResource(R.drawable.ic_arrow_right);
holder.hideShowL0Layout.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(view -> {
Util.Logd("////////////////////////");
if (oldL0ClickPosition >= 0) {
if (listQRL0.get(oldL0ClickPosition).isL0Expanded()) {
listQRL0.get(oldL0ClickPosition).setL0Expanded(false);
holder.hideShowL0Layout.setVisibility(View.GONE);
Util.Logd("Id to close is "+listQRL0.get(oldL0ClickPosition).getId());
isFromClose = true ;
notifyItemChanged(oldL0ClickPosition);
}
}
if (oldL0ClickPosition == holder.getAdapterPosition()) {
oldL0ClickPosition = -1;
} else {
oldL0ClickPosition = holder.getAdapterPosition();
}
Util.Logd("New click is " + oldL0ClickPosition);
if (oldL0ClickPosition >= 0 && oldL0ClickPosition != -1) {
new Handler(Looper.myLooper()).postDelayed(() -> {
listQRL0.get(oldL0ClickPosition).setL0Expanded(!listQRL0.get(oldL0ClickPosition).isL0Expanded());
Util.Logd("new data modify is "+listQRL0.get(oldL0ClickPosition).getId());
isFromClose = false ;
notifyItemChanged(oldL0ClickPosition);
},500);
}
});
}
#Override
public int getItemCount() {
return listQRL0.size();
}
public class LstQRL0ViewHolder extends RecyclerView.ViewHolder {
private TextView mSeason, mStyle, mVendor;
private ImageView mLstQrL0ImageView;
private LinearLayout hideShowL0Layout;
public LstQRL0ViewHolder(#NonNull View itemView) {
super(itemView);
mSeason = itemView.findViewById(R.id.lstqrl0_season);
mStyle = itemView.findViewById(R.id.lstqrl0_style);
mVendor = itemView.findViewById(R.id.lstqrl0_vendor);
mLstQrL0ImageView = itemView.findViewById(R.id.lstqr10_arrow);
mLstQRL1InfoRecView = itemView.findViewById(R.id.lstqrl1info_rv);
hideShowL0Layout = itemView.findViewById(R.id.hideShowL0Layout);
}
}
}
There is one more nested adapter but thats also same , so am not posting that here.
If need any help then just post comment.

Observe LiveData from ListView current Item

Basically i want to retrieve a int(score) generated from the current ListViewItem and assign it back to concrete TextView in my ListView.I am using SharedViewModel with LiveData but when i observe nothing happens.I am using Nav Architecture Component with Single activity.I'll be glad if someone helps.Thank u , here's some code.
public class ListFrag extends Fragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getCurrentScore().observe(getViewLifecycleOwner(), new Observer<Integer>() {
#Override
public void onChanged(#Nullable Integer s) {
for (int i = 0; i < myListView.getAdapter().getCount(); i++) {
v = myListView.getAdapter().getView(i,null, myListView);
finalScore = v.findViewById(R.id.finalScoreView);
if (s != null) {
itemAdapter = new ItemAdapter(getActivity(),items,bushido,description,s,finalScore);
myListView.setAdapter(itemAdapter);
finalScore.setText(String.valueOf(s));
}
((BaseAdapter)myListView.getAdapter()).notifyDataSetChanged();
}
}
});
}
public class SharedViewModel extends ViewModel
{
private MutableLiveData<Integer> currentScore = new MutableLiveData<>();
public LiveData<Integer> getCurrentScore(){
return currentScore;
}
public void setCurrentScore(Integer finito) {
currentScore.setValue(finito);
}
}
public class ItemAdapter extends BaseAdapter {
LayoutInflater mInflater;
String[] items;
String[] bushido;
String[] description;
TextView finalscorre;
Integer scr;
public ItemAdapter(Context c,String[] i ,String [] p ,String[] d, Integer scc,TextView sc) {
items = i;
bushido = p;
description = d;
finalscorre = sc;
scr = scc;
mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int i) {
return items[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup parent) {
View v = mInflater.inflate(R.layout.my_listview_detail, null);
TextView nameTextView = v.findViewById(R.id.NameTextView);
TextView bushidoTextView = v.findViewById(R.id.bushidoTextView);
TextView descriptionTextView = v.findViewById(R.id.descriptionTextView);
finalscorre = v.findViewById(R.id.finalScoreView);
String name = items[i];
String desc = description[i];
String bush = bushido[i];
finalscorre.setText("Waat");
nameTextView.setText(name);
descriptionTextView.setText(desc);
bushidoTextView.setText(bush);
ItemAdapter.this.notifyDataSetChanged();
return v;
}
}
When i try to assign the LiveData in TextView out of the ListView it works.But when i try this ,nothings happen (no errors and no result).
Adapters act as a bridge between the data (in your case, the string array you pass into the adapter), and the ListView (in your case, myListView). Any change to the ListView needs to be follow these steps:
make desired changes to the data itself
pass this new data to the adapter
adapter updates the list view
I have wrote some example code:
ItemAdapter
public class ItemAdapter extends BaseAdapter {
LayoutInflater mInflater;
String[] items;
String[] bushido;
String[] description;
// TextView finalscorre; // I commented out this TextView please see the comment below
Integer scr;
public ItemAdapter(Context c,String[] i ,String [] p ,String[] d, Integer scc,TextView sc) {
items = i;
bushido = p;
description = d;
// finalscorre = sc;
scr = scc;
mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void updateItems(String[] i, String[] p, String[] d, Integer scc) {
items = i;
bushido = p;
description = d;
scr = scc;
// notify the adapter to refresh the list view.
notifyDataSetChanged()
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int i) {
return items[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup parent) {
View v = mInflater.inflate(R.layout.my_listview_detail, null);
TextView nameTextView = v.findViewById(R.id.NameTextView);
TextView bushidoTextView = v.findViewById(R.id.bushidoTextView);
TextView descriptionTextView = v.findViewById(R.id.descriptionTextView);
//finalscorre = v.findViewById(R.id.finalScoreView);
TextView finalscorre = v.findViewById(R.id.finalScoreView);
String name = items[i];
String desc = description[i];
String bush = bushido[i];
// finalscorre.setText("Waat");
finalscorre.setText(scr);
nameTextView.setText(name);
descriptionTextView.setText(desc);
bushidoTextView.setText(bush);
// ItemAdapter.this.notifyDataSetChanged(); Do NOT call this method inside getView
return v;
}
}
Fragment
public class ListFrag extends Fragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Create and set adapter just once. Do not create or set new adapter in observer, for loop, etc.
itemAdapter = new ItemAdapter(getActivity(),items,bushido,description,s,finalScore);
myListView.setAdapter(itemAdapter);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getCurrentScore().observe(getViewLifecycleOwner(), new Observer<Integer>() {
#Override
public void onChanged(#Nullable Integer s) {
itemAdapter.updateItems(items,bushido,description,s);
}
});
}
}
I wasn't able to figure out what finalscorre supposed to be so I assumed that this is the text view that stores the final score that you mentioned, and all list view items should have the same value. If this is not the case please clarify in your question.
Also note that while this solution is enough to solve the specific problem you mentioned, their are some other improvements that can be made:
Use RecyclerView instead of ListView.
Instead of maintaining multiple String[], define a POJO that represent the item, and have a single array.
Also, checking this adapter implementation in google sample will help.
inside adapter you are doing nothing that will update your LiveData

Realm Array of Strings in Android

I have been trying to store an array of strings in Realm database programmatically as given below:
Model Class:
public class Station extends RealmObject {
private String name;
// ... Generated getters and setters ...
}
Saving Data:
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
Station station1 = realm.createObject(Station.class)
station1.setName(name1);
Station station2 = realm.createObject(Station.class)
station2.setName(name2);
//goes on till station8000
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
// ...
});
Is there an alternate best way for this?
Why yes of course there is
public class Station extends RealmObject {
private String name;
// ... Generated getters and setters ...
}
and
// field variable
RealmResults<Station> stations;
// field variable
RealmChangeListener<RealmResults<Station>> changeListener = new RealmChangeListener<RealmResults<Station>>() {
#Override
public void onChange(RealmResults<Station> results) {
// handle onSuccess()
}
}
and
stations = realm.where(Station.class).findAll();
stations.addChangeListener(changeListener);
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
Station station = new Station();
for(String stationName : listOfStationNames) {
station.setName(stationName);
realm.insert(station);
}
}
});
EDIT: Check out this sexy spinner.
public class DropdownSpinnerAdapter
extends BaseAdapter
implements SpinnerAdapter {
private static final String TAG = "DropdownSpinnerAdapter";
private boolean isItemSelected;
RealmResults<Station> content;
public ResultDropdownSpinnerAdapter(RealmResults<Station> objects) {
this.content = objects;
}
#Override
public int getCount() {
if(content == null || !content.isValid()) {
return 1;
}
return content.size() + 1;
}
#Override
public String getItem(int position) {
if(position <= 0) {
return "";
}
return content.get(position - 1);
}
#Override
public long getItemId(int position) {
return position;
}
public int findPosition(Station selectedItem) {
for(int i = 0, s = content.size(); i < s; i++) {
Station item = content.get(i);
if(item.equals(selectedItem)) {
return i + 1;
}
}
return 0;
}
static class ViewHolder {
TextView textView;
ImageView imageView;
public ViewHolder(View convertView) {
textView = ButterKnife.findById(convertView, R.id.dropdown_textview);
imageView = ButterKnife.findById(convertView, R.id.dropdown_arrow);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView != null) {
if(!(convertView instanceof DropdownHeaderView)) {
convertView = null;
}
}
if(convertView == null) {
convertView = LayoutInflater.from(parent.getContext())
.inflate((isItemSelected) ? R.layout.dropdown_selected : R.layout.dropdown,
parent,
false);
ViewHolder viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.textView.setText(getItem(position).getName());
return convertView;
}
public void setItemSelected(boolean selected) {
this.isItemSelected = selected;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if(convertView != null) {
if(!(convertView instanceof DropdownView)) {
convertView = null;
}
}
if(convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.dropdown_noarrow, parent, false);
ViewHolder viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.textView.setText(getItem(position).getName());
return convertView;
}
public void updateContent(RealmResults<Station> content) {
this.content = content;
notifyDataSetChanged();
}
}

how to fix Integer cannot be cast in ViewHolder

I have adapter and retrieving the details into listview
private class ChatDisplayAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ChatDisplayAdapter() {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
private class ViewHolder {
TextView chatTitle;
TextView chatPlace;
TextView chatDate;
TextView notificationCount;
}
#Override
public int getCount() {
return groupEventMoList.size();
}
#Override
public Object getItem(int position) {
return groupEventMoList.get(position);
}
#Override
public long getItemId(int id) {
// for sqllite management
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.chatwindow, null);
holder = new ViewHolder();
convertView.setClickable(true);
convertView.setFocusable(true);
holder.chatTitle = (TextView) convertView.findViewById(R.id.chat_title);
holder.chatPlace = (TextView) convertView.findViewById(R.id.event_place);
holder.chatDate = (TextView) convertView.findViewById(R.id.event_date);
holder.notificationCount = (TextView) convertView.findViewById(R.id.notification_count);
holder.chatPlace.setTextColor(getResources().getColor(R.color.black));
holder.chatDate.setTextColor(getResources().getColor(R.color.black));
holder.chatTitle.setTextColor(getResources().getColor(R.color.black));
holder.notificationCount.setTextColor(getResources().getColor(R.color.black));
convertView.setTag(holder);
//Log.e("view", "holder" + convertView.getTag());
}
else {
// Log.e("view", "holder" + convertView.getTag());
holder = (ViewHolder) convertView.getTag();
// Log.e("view", "holder" + holder);
}
// holder = (ViewHolder) convertView.getTag();
convertView.setTag(groupEventMoList.get(position));
holder.chatPlace.setText(groupEventMoList.get(position).getPlace());
holder.notificationCount.setText(Integer.toString(groupEventMoList.get(position).getCount()));
holder.chatTitle.setText(groupEventMoList.get(position).getText());
String actualDate = groupEventMoList.get(position).getEventDate();
Log.e("view", "notification" + groupEventMoList.get(position).getCount());
Log.e("view", "after notification position" + position);
try {
//date format changed here
Date formatDate = new SimpleDateFormat("yyyy-MM-dd").parse(actualDate);
dateResult = new SimpleDateFormat("dd-MM-yyyy").format(formatDate);
holder.chatDate.setText(dateResult);
} catch (ParseException e) {
e.printStackTrace();
}
Log.e("view", "position" + groupEventMoList.get(position).getPlace());
final EventMO eventMO = groupEventMoList.get(position);
convertView.setTag(position);
View v = convertView.findViewById(R.id.chat_window_single);
v.getRootView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("position", v.getTag().toString());
Intent groupAct = new Intent(context, GroupChatActivity.class);
groupAct.putExtra("eventMo", eventMO);
groupAct.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(groupAct);
}
});
return convertView;
}
}
}
this is my log
12-30 17:19:54.324 17652-17652/com.ringee.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.ClassCastException: java.lang.Integer cannot be cast to com.ringee.app.GroupChatFragment$ChatDisplayAdapter$ViewHolder
at com.ringee.app.GroupChatFragment$ChatDisplayAdapter.getView(GroupChatFragment.java:345)
I have the error exactly at else part. how to fix this issue
I am getting error near this line : holder = (ViewHolder) convertView.getTag();
and holder returns as 0
You are setting the view tag three times. Notice the lines:
convertView.setTag(holder);
...
convertView.setTag(groupEventMoList.get(position));
...
convertView.setTag(position);
With the last line, you are setting an Integer as a tag and thats why you get ClassCastException.
Remove the excess setTags and leave only the first, correct one.
Similar cases here and here.

Refresh list and adapter when DB changed in custom Adapter

my project is todo
i have 4 tab , 4 fragment with 4 list(Actionbar navigation contain 4 tab and ViewPager).
4 list(tab) use same db table but each of them retrieve different data with categoryID.
i use a Asynctask for all of them ,to read data and set adapter to list.
public class AsyncTaskDB extends AsyncTask<Void, Void, listAdapter> {
Context act;
int Categoryid;
ArrayList<memo> arraymemo;
listAdapter myadapter;
ListView list;
listAdapter listAdp;
public AsyncTaskDB(Context acti, int categoryID) {
this.act = acti;
this.Categoryid = categoryID;
}
#Override
protected listAdapter doInBackground(Void... params) {
MemoDBHelper helper = new MemoDBHelper(act);
// getAllDataByCategoryID
if (Categoryid != CategoryID.Done_ID)
arraymemo = helper.getAllTaskByCategory(Categoryid);
else
arraymemo = (ArrayList<memo>) helper.gatDoneMemo();
myadapter = new listAdapter(act, arraymemo);
if (myadapter == null) {
Toast.makeText(act, "no data", Toast.LENGTH_SHORT).show();
cancel(true);
}
return myadapter;
}
#Override
protected void onPostExecute(listAdapter result) {
switch (Categoryid) {
case CategoryID.Urgent_Imprtant_ID:
list = (ListView) ((Activity) act)
.findViewById(R.id.Urgent_Important_list);
break;
case CategoryID.Urgent_Less_Imprtant_ID:
list = (ListView) ((Activity) act)
.findViewById(R.id.Urgent_Less_Important_list);
break;
case CategoryID.Less_Urgent_Imprtant_ID:
list = (ListView) ((Activity) act)
.findViewById(R.id.Less_Urgent_Imprtant_list);
break;
case CategoryID.Neither_Urgent_Or_Imprtant_ID:
list = (ListView) ((Activity) act)
.findViewById(R.id.Neither_Urgent_Imprtant_list);
break;
case CategoryID.Done_ID:
list = (ListView) ((Activity) act).findViewById(R.id.ArchiveList);
break;
}
list.setAdapter(result);
this.listAdp = result;
}
public listAdapter getlistAdapter() {
return this.listAdp;
}
}
each memo in list have Done CheckBox.when user check and uncheck it,automatically memo update in db.(in custom adapter)
----------------------------
| -- |
| | | memotitle |
| -- |
----------------------------
public class listAdapter extends BaseAdapter implements OnCheckedChangeListener { Context act;
ArrayList<memo> MemoArray;
SparseBooleanArray mcheck;
int pos;
MemoDBHelper helper;
public listAdapter(Context activity, ArrayList<memo> memoarray) {
this.act = activity;
this.MemoArray = memoarray;
mcheck = new SparseBooleanArray(memoarray.size());
helper = new MemoDBHelper(act);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return MemoArray.size();
}
#Override
public memo getItem(int position) {
// TODO Auto-generated method stub
return MemoArray.get(position);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
public class viewHolder {
TextView title;
// TextView description;
CheckBox chkstatus;
}
viewHolder it;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
pos = position;
LayoutInflater in = ((Activity) act).getLayoutInflater();
if (convertView == null) {
convertView = in.inflate(R.layout.list_item, null);
it = new viewHolder();
it.title = (TextView) convertView.findViewById(R.id.txt_list_title);
it.chkstatus = (CheckBox) convertView
.findViewById(R.id.chkStatusid);
convertView.setTag(it);
} else {
it = (viewHolder) convertView.getTag();
}
it.title.setText(MemoArray.get(position).GetTitle());
it.chkstatus.setChecked(MemoArray.get(position).GetSattus());
it.chkstatus.setOnCheckedChangeListener(this);
it.chkstatus.setTag(String.valueOf(MemoArray.get(position).GetID()));
return convertView;
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mcheck.put(Integer.valueOf((String) buttonView.getTag()), isChecked);
helper.updateStatusByID(Integer.valueOf((String) buttonView.getTag()),
(isChecked));
helper.close();
//after db updatedt ,call method in fragment to notifydatsetchanged!
UrgentImportant_frg.notifyAdapter();
}
}
adapter must notify data changed ,and list don't show done memo.i don't how to do it !
my first fragment :
public class UrgentImportant_frg extends Fragment {
static listAdapter myadp;
ListView list;
// memo selectedmemo;
long[] checkid;
AsyncTaskDB asyn;
ArrayList<memo> selectedMemoArray;
final static int RQS_MoveTo = 10;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.urgentimportant_layout,
container, false);
return rootview;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
selectedMemoArray = new ArrayList<memo>();
list.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.list_select_menu, menu);
/*
* MenuInflater inflater = getActivity().getMenuInflater();
* inflater.inflate(R.menu.list_select_menu, menu);
*/
mode.setTitle("Select Items");
return true;
}
#Override
public boolean onActionItemClicked(final ActionMode mode,
MenuItem item) {
switch (item.getItemId()) {
case R.id.deletemenu:
final int[] myitemsid = getSelectedID();
final MemoDBHelper helper = new MemoDBHelper(getActivity());
AlertDialog.Builder myAlert = new AlertDialog.Builder(
getActivity());
myAlert.setMessage(
"Are you sure to delete " + myitemsid.length
+ " memo ?")
.setPositiveButton("yes", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
for (int j = 0; j < myitemsid.length; j++) {
helper.deleteRow(myitemsid[j]);
/*
* if (j == myitemsid.length - 1) {
* strid[j] = String
* .valueOf(myitemsid[j]); } else {
* strid[j] = String
* .valueOf(myitemsid[j]) + ","; }
*/
}
mode.finish();
onResume();
}
}).setNegativeButton("no", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
mode.finish();
}
});
AlertDialog alert = myAlert.create();
alert.show();
// mode.finish();
break;
case R.id.MoveTomenu:
// myadp.getItem(position);
Intent i = new Intent(getActivity(),
MoveToCategory_act.class);
i.putExtra("categoryid", CategoryID.Urgent_Imprtant_ID);
startActivityForResult(i, RQS_MoveTo);
mode.finish();
break;
}
return true;
}
// get selected id to delete and move category
#Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
if (myadp == null) {
myadp = asyn.getlistAdapter();
}
int p = ifMemoSelectedBefore(myadp.getItem(position));
if (p != -1) {
selectedMemoArray.remove(p);
} else if (checked) {
selectedMemoArray.add(myadp.getItem(position));
}
final int checkedCount = list.getCheckedItemCount();
switch (checkedCount) {
case 0:
mode.setSubtitle(null);
break;
case 1:
mode.setSubtitle("One Item Selected");
break;
default:
mode.setSubtitle(checkedCount + " Item Selected");
break;
}
}
});
getActivity().getActionBar().setSubtitle("subtitle");
}
public int ifMemoSelectedBefore(memo m) {
return selectedMemoArray.indexOf(m);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
list = (ListView) view.findViewById(R.id.Urgent_Important_list);
// -------------click item
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
if (myadp == null) {
myadp = asyn.getlistAdapter();
}
// Log.d("tag", myadp.getItem(position).GetTitle() + "");
Intent nextintent = new Intent(getActivity(),
EditMemo_act.class);
memo g = myadp.getItem(position);
/*
* MemoDBHelper helper = new MemoDBHelper(getActivity());
* helper.updateStatusByID(g.GetID(), true);
*/
nextintent.putExtra("editmemo", g);
startActivity(nextintent);
}
});
}
#Override
public void onResume() {
asyn = new AsyncTaskDB(getActivity(), CategoryID.Urgent_Imprtant_ID);
asyn.execute();
super.onResume();
}
public int[] getSelectedID() {
int[] SelectedArray_ID = new int[selectedMemoArray.size()];
for (int j = 0; j < selectedMemoArray.size(); j++) {
SelectedArray_ID[j] = selectedMemoArray.get(j).GetID();
// Log.d("id", selectedMemoArray.get(j).GetID() + "");
}
return SelectedArray_ID;
}
//-------------a method to notifymyadpter
public static void notifyAdapter() {
if (myadp != null) {
myadp.notifyDataSetChanged();
Log.d("notify", "here");
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RQS_MoveTo) {
if (resultCode == Result.RESULT_OK) {
int id = data.getExtras().getInt("NEWCategoryID");
MemoDBHelper helper = new MemoDBHelper(getActivity());
final int[] myitemsid = getSelectedID();
for (int j = 0; j < myitemsid.length; j++) {
helper.updateCategory(myitemsid[j], id);
}
onResume();
}
}
}
}
is there any method in fragment to run after adapter changed?or in myadapter ,after db updated i call a method in fragment to notify data changed ? i think the second solution isn't right >_<
p.s:notifyAdapter() doesn't work,is it because my adapter fill in asyntask ?
When the adapter changed, try to call below method.
Once you use FragmentPagerAdapter or ListView, when you change the data, you should call this.
notifyDataSetChanged();
read about it : notifyDataSetChanged

Resources