I have a strange problem in my ListView and I don't understand why it happens.
In my checklist when I select 3 or more items only last and first Item are deleted the second item is not deleted. It just remains selected and I need to click this post button again.
SendDataFragment Activity
btn_DataSend=(Button) getActivity().findViewById(R.id.trn_post_btn);
btn_DataSend.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
StringBuffer responseText = new StringBuffer();
responseText.append("The following were selected...\n");
//get All info like custID, mStatus mTrnNo mCustID mCustName
List<customerInfo> stateList = adapter.mCategories;
for(int i=0;i<stateList.size();i++)
{
customerInfo state = stateList.get(i);
if(state.ismStatus())
{
//postData(state.getmTrnNo());
int c = i;
dbManager.delete_ShipmentDetails(state.getmCustID());
stateList.remove(i);
}
}
adapter.notifyDataSetChanged();
Toast.makeText(getActivity(), responseText, Toast.LENGTH_LONG).sho();
}
});
DBManager
public void delete_ShipmentDetails(String id){
SQLiteDatabase db = dbHelper.getReadableDatabase();
db.execSQL("delete from "+ DatabaseHelper.TBL_OE_SHIPMENT_H +" WHERE " +DatabaseHelper.OE_SHIPMENT_H_CUSTID+"="+id);
}
My App screen-shots are:
Use loop in reverse order
for(int i = stateList.size()-1; i >= 0; i--){
customerInfo state = stateList.get(i);
if(state.ismStatus())
{
//postData(state.getmTrnNo());
int c = i;
dbManager.delete_ShipmentDetails(state.getmCustID());
stateList.remove(i);
notifyItemRemoved(i);
}
}
adapter.notifyDataSetChanged();
This is because you are looping through a list whilst changing the length of it.
There are several methods to solve this problem, either loop through the list backwards, use an iterator or save the deletions until the end. In order to change the loop to use an iterator the following should work as expected:
Iterator<Integer> it = stateList.iterator();
while (it.hasNext()) {
customerInfo state = it.next();
if(state.ismStatus()) {
dbManager.delete_ShipmentDetails(state.getmCustID());
it.remove();
}
}
adapter.notifyDataSetChanged();
Now I Get It Clearly I have also made another Way Just Change here like
for(int i=0;i<stateList.size();i++)
{
customerInfo state = stateList.get(i);
if(state.ismStatus())
{
postData(state.getmTrnNo());
dbManager.delete_ShipmentDetails(state.getmCustID());
stateList.remove(i);
i--;
}
}
adapter.notifyDataSetChanged();
});
Related
Each item has a unique code.
Item also have name it doesn't have to be unique.
Everything I add a code, if the code doesn't exist it will ask the name.
If the code does exists, it it will only print out the below statement and 'break';
System.out.println("Already exists");
But when I type the same item code again.
Not only it print out the statement, it also still ask me the name.
Here is my code
String code = //scannerobject;
for(Item item: items)
if(item..getCode().equals(code))) {
System.out.println("Already exists");
break;
}
String itemName = //scannerobject
item.add(new Item(code,itemName));
.getCode() is just return method from Item class
private String code;
public String getCode(){
return code;
}
Can someone explain to me?
Thanks.
If I understood correctly, before adding a new item you want to check if the code is fresh. So, you need to make sure the loop has been finished without break and all items code has been checked. For performance improvement, you may want to consider binary tree to check for used code in O(log n).
String code = //scannerobject;
boolean isFresh = true;
for(Item item: items) {
if(item.getCode().equals(code))) {
System.out.println("Already exists");
isFresh = false;
break;
}
}
if(isFresh){
String itemName = //scannerobject
items.add(new Item(code,itemName));
} else {
//maybe exit or continue to outer while
}
You need to check if the object has not been found with some condition once the loop terminates.
String code = //scannerobject;
int i;
for(i = 0; i < items.size(); i++) {
if(items.get(i).getCode().equals(code))) {
System.out.println("Already exists");
break;
}
}
if(i == items.size()) {
String itemName = //scannerobject
items.add(new Item(code, itemName));
}
We need to check the flag and ask for the itemName outside the for loop so that every item is checked.
String code = //scannerobject;
Boolean flag=true;
for(Item item: items) {
if(item..getCode().equals(code))) {
System.out.println("Already exists");
flag = false;
break;
}
}
if(flag){
String itemName = //scannerobject
item.setName(itemName);
}
I want to update a list in my activity that depends on the data of another list. Both the data list are being observed from the activity from the my viewmodel. After I get the data from my firstlist I need to run a for loop on this list to get the required ids and get the data for the second list.
But keeping the livedata observer in the for loop is causing a lot of problems. The for loop runs as expected but the livedata observer is getting called almost double the amount of the for loop. This happens only the first time when the list in being brought from the api. When I do the same operation a second time where the list is cached and is being brought from the database, the problem does not occur. Below is the source code for the problem,
for (int i = 0; i < firstList.size(); i++) {
final String uId = firstList.get(i).item.uid;
final long id = firstList.get(i).item.id;
viewModel.initAnotherItemRepository(uId, id);
viewModel.getSecondItem().observe(this, new Observer<Resource<List<SecondItem>>>() {
#Override
public void onChanged(Resource<List<SecondItem>> listResource) {
if (listResource.data != null) {
secondItemList.addAll(listResource.data);
if (count == firstList.size() - 1) {
//Do something
}
count = count + 1;
}
if (listResource.state == Resource.STATE_FAILURE) {
showLoadingSpinner(false);
}
}
}
);
}
Try to observe SecondItem outside the for loop. It gets data whenever update
viewModel.getSecondItem().observe(this, new Observer<Resource<List<SecondItem>>>() {
#Override
public void onChanged(Resource<List<SecondItem>> listResource) {
if (listResource.data != null) {
secondItemList.addAll(listResource.data);
if (count == firstList.size() - 1) {
//Do something
}
count = count + 1;
}
if (listResource.state == Resource.STATE_FAILURE) {
showLoadingSpinner(false);
}
}
}
);
for (int i = 0; i < firstList.size(); i++) {
final String uId = firstList.get(i).item.uid;
final long id = firstList.get(i).item.id;
viewModel.initAnotherItemRepository(uId, id);
}
I am suing multi select spinner to update languages to the server using retrofit. but when i select multi options from spinner it returns a boolean array and the selected value returns as true and the others as false. now i need to get the value against each title using the index and store them into an array and send that array to server to update my record. here is the image that explain it.
This image is showing the boolean array which returns true against each selected value and the other array is my data i have to show the user the title and on the back end i have to send the value against each title .
this is the code i which i have to not able to get the array of values against each selected title. please help
Call<List<EnglishLevel>> call_english = RetrofitClient.getInstance().getApi().getenglishlist("english_levels");
call_english.enqueue(new Callback<List<EnglishLevel>>() {
#Override
public void onResponse(Call<List<EnglishLevel>> call, Response<List<EnglishLevel>> response) {
arrayList_english =response.body();
for (EnglishLevel C:arrayList_english){
if (C.getTitle() != null){
Log.d("English level" , C.getTitle());
final String[] levelName = new String[arrayList_english.size()];
for (int i=0 ; i<arrayList_english.size() ; i++){
levelName[i]= arrayList_english.get(i).getTitle();
}
ArrayAdapter<String> adapter= new ArrayAdapter <String>(SearchActivity.this,
android.R.layout.simple_list_item_multiple_choice,
levelName);
english.setListAdapter(adapter).setListener(new MultiSelectSpinner.MultiSpinnerListener() {
#Override
public void onItemsSelected(boolean[] selected) {
ArrayList<String> toSend = new ArrayList<>();
for(int j = 0; j < arrayList_english.size(); j++){
if(selected[j]) {
toSend.add(arrayList_english.get(j).getValue());
}
}
//
}
})
.setSelectAll(false).setMinSelectedItems(0);
}
}
}
#Override
public void onFailure(Call<List<EnglishLevel>> call, Throwable t) {
Toast.makeText(SearchActivity.this , t.getMessage() , Toast.LENGTH_SHORT).show();
}
});
In the above code that i have issue with some part of it...
english.setListAdapter(adapter).setListener(new MultiSelectSpinner.MultiSpinnerListener() {
#Override
public void onItemsSelected(boolean[] selected) {
ArrayList<String> toSend = new ArrayList<>();
for(int j = 0; j < arrayList_english.size(); j++){
if(selected[j]) {
toSend.add(arrayList_english.get(j).getValue());
}
}
//
}
in onItemSelected i have to get array of each selected title's value.
in this problem you need to define your ArrayList toSend = new ArrayList<>(); as a globally in existing scenario you are creating new array list every time when you select one language from spinner
Ok this might seem easy but its been bugging my mind for days and I honestly don't know why it the index wont increase and get the other data. I dont know where to but the return. I placed it in 2 lines and the first one only gives the first row of data from the database and the second one only gives the last one from the database. (See commented out lines below). How to get each row that fits the if-statements?
Here's my code:
public Object[] populateTable(ArrayList<Outlet> outletList, String selection, int size, int monthCtr, String selDay){
for(int i = 0; i<outletList.size(); i++){
if(outletList.get(i).getCity().equalsIgnoreCase(selection)){
if(outletList.get(i).getStatus().equals("ACTIVE")){
bar = outletList.get(i).getBarangay();
code = Integer.toString(outletList.get(i).getCode());
name = outletList.get(i).getName();
data = new Object[]{bar, name, code};
//return data ->gives the first one in the database
}
}
}
}
//return data -> gives the last one in the database
}
You need to save all your results in another array and return that instead.
public Object[] populateTable(ArrayList<Outlet> outletList, String selection, int size, int monthCtr, String selDay)
{
List<object> result = new List<object>();
for(int i = 0; i<outletList.size(); i++)
{
if(outletList.get(i).getCity().equalsIgnoreCase(selection))
{
if(outletList.get(i).getStatus().equals("ACTIVE"))
{
bar = outletList.get(i).getBarangay();
code = Integer.toString(outletList.get(i).getCode());
name = outletList.get(i).getName();
data = new Object[]{bar, name, code};
result.Add(data);
}
}
}
return result.ToArray();
}
try this:
public List<Outlet> populateTable(ArrayList<Outlet> outletList, String selection, int size, int monthCtr, String selDay){
List<Outlet> data = new ArrayList<Outlet>();
for(int i = 0; i < outletList.size(); i++){
if(outletList.get(i).getCity().equalsIgnoreCase(selection) &&
outletList.get(i).getStatus().equals("ACTIVE")){
data.add(outletList.get(i));
}
}
return data;
}
Your problem here is as follow:
Your first return statement, will exit the for loop, and return
the first object, as your results have shown.
Your second return statement, will, as you have explained, only
return the last record that was iterated over in the for loop.
Your third problem is on this line data = new Object[]{bar, name,
code};. After every loop, you instantiate the data object to a new
array of objects, instead of adding the values to the array, so essentially, you are always creating an array of objects with 1 item in it, the last one that was iterated.
If you want to return all objects in the array, you should try the following:
public Object[] populateTable(ArrayList<Outlet> outletList, String selection, int size, int monthCtr, String selDay)
{
Object[] result = new Object[outletList.size()];
for (int i = 0; i < outletList.size(); i++)
{
if (outletList.get(i).getCity().equalsIgnoreCase(selection))
{
if (outletList.get(i).getStatus().equals("ACTIVE"))
{
bar = outletList.get(i).getBarangay();
code = Integer.toString(outletList.get(i).getCode());
name = outletList.get(i).getName();
var data = new { bar, name, code };
result[i] = data;
}
}
}
return result;
}
I'm trying to print the contents of my checkbox list. I'd like to display all the unchecked (false values) and checked (true values) in the order that it appears in the list view. So far I can only get the true values, how can I get the unchecked false values?
public void selection (){
final ListView lv = (ListView)findViewById(R.id.treeQuestionsList);
Intent intent = getIntent();
int id2 = intent.getIntExtra("id2", 0);
SparseBooleanArray checked = lv.getCheckedItemPositions();
int size = checked.size();
for (int i = 0; i < size; i++) {
int key = checked.keyAt(i);
entries.add(new Observation(id2,lv.getCheckedItemPositions().get(key)));
Log.d(Constants.TAG,"--ID:="+id2+"--checkeddata----"+ entries.get(i).answers);
}
}
From the documentation available on Android Developers, you might need to use a combination of the value along with the key in order to get the desired result.
for (int i=0; i < checked.size(); i++) {
if (checked.valueAt(i)) {
int key = checked.keyAt(i);
Log.i(TAG, key + " is selected");
} else {
int key = checked.keyAt(i);
Log.i(TAG, key + " is not selected");
}
}
You can also take a look at what getCheckedItemPositions() does.