I have a structure made from ListView - Customised as seen in Image Below
I can add New Products on Click of AddProduct Button
A new Category gets added with EditText of Product and Quantity
On that I have a (+) and (-) button which adds subcategory for Enter Dealer and Quantity with remove button on it .
The structure has been good .
But the data maintenance on it difficult . Like when I scroll , the focus gets lost and the data goes else where on ListView .
Kindly suggest some code for this .
I suggest to you to change the navigation structure.
You can keep the delete feature on the listView maybe implementing the swipe as it happens for example in GMail.
I would remove the add button and use FAB (Floating action Button) as Material guide lines suggest.
Hope it will help you!
I have implemented this thing with the following structure.
First of all I have created Model class for maintain data of Product.
I am saving data in JSONArray with collection of JSONObject of quantity added. (I have used JSON because I can save easily as a String in Preference.)
In onCreate of Activity I am creating SparseArray of Saved Products from JSONArray like:
try {
JSONArray savedProdJSONArray = new JSONArray(productSharedPref.getString("productArray", new JSONArray().toString()));
Log.i(TAG, "Saved ARRAY Count : " + productSharedPref.getInt("count", -1));
for (int i = 0; i < savedProdJSONArray.length(); i++) {
ProductItems tempPItems = new ProductItems();
tempPItems.setProdId(savedProdJSONArray.getJSONObject(i).getInt("prod_id"));
tempPItems.setProdQty(savedProdJSONArray.getJSONObject(i).getDouble("qty"));
tempPItems.setProdName(savedProdJSONArray.getJSONObject(i).getString("name"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e(TAG, "Json Err variant:"+e.getLocalizedMessage());
}
Now in getView() of Adapter I am checking with current ProductId and Saved ProductId is matched. If it is then fill up EditText with saved data like:
/** First check whether value of Saved product Array is >0 or not..*/
ProductItems savedProdTemp = prodItemsSavedList.get(holder.prodId, null);
if(savedProdTemp != null)
{
productQtyValue = savedProdTemp.getProdQty();
holder.prodQtyView.setText(""+productQtyValue);
} else {
holder.prodQtyView.setText("");
}
Here you also have to addTextChangeListner for EditText to save data in ArrayList and then you have to Convert in JSONArray when Activity is Stop or Pause
I think it is little bit confusing but I thought it is only helps you. I tried many times to find out solution but didn't better than this.
Hope it will help you.
Welcomes you if you have any question. (Sorry If you found English Mistake :D)
Related
Let's say I have implemented an infinite scrolling list using Paging Library, but now I want to give the user an option to sort the data at client side, how can I do it? For example, I have movies data, the Paging library is working fine to load all movies, but how can I sort the movies based on say rating or release date.
Any help would be appreciated.
I haven't tried this method but hope it works .
Assuming you use RecyclerView to show the list (because it is much easier in recyclerView)
When you get the first ten item from server and you choose to sort it.Lets say by name(ascending) .You have to use two ArrayList here:
1:finalArrayList :- which contains all the whole list
2:updateArrayList :- which has the latest ten result
when you choose to sort (onButtonClick)
updateArrayList = new ArrayList<>();
updateArrayList.addAll(finnalArrayList);
Collections.sort(updateArrayList, new Comparator<StoreModel>() {
public int compare(StoreModel obj1, StoreModel obj2) {
// ## Ascending order
if (sortingBy == 0) {
return obj1.getName().compareToIgnoreCase(obj2.getName());
}});
adapter.clear();
adapter.addAll(updateArrayList);
Run this code only when the button is clicked
Now when you scroll down and more data comes
updateArrayList = new ArrayList<>();
updateArrayList.add(StoreModel)//Add the latest ten data from the response
and sort it before sending it to adapter
Collections.sort(updateArrayList, new Comparator<StoreModel>() {
public int compare(StoreModel obj1, StoreModel obj2) {
// ## Ascending order
if (sortingBy == 0) {
return obj1.getName().compareToIgnoreCase(obj2.getName());
}});
adapter.addAll(updateArrayList);
hope you got it and hope it works.Cheers:)
final FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter(Service.class, R.layout.browse_service_detail, ServiceHolder.class, mReference){
#Override
protected void populateViewHolder(ServiceHolder serviceHolder, Service service, int position) {
serviceHolder.setServiceName(service.getName());
serviceHolder.setInfo("От " + service.getPrice1());
service.setQuantitySelected(service.getQuantityEnabled());
if (Order.getInstance().getServices() != null) {
for (Service serviceFromSingleton : Order.getInstance().getServices()) {
if (serviceFromSingleton.getName() == serviceHolder.getServiceName().getText().toString()) {
serviceHolder.getServiceName().setSelected(true);
serviceHolder.getServiceName().setTextColor(getResources().getColor(R.color.yellow));
}
}
}
//add item to array
servicesList.add(service);
}
}
};
When I run this activity, it records the visible list objects to an array, but when I scroll down and go back up, it duplicates the first elements again into the array. How to fix it? For an item to be added only once.
I don't think there is any issue in RecyclerAdapter..I think the list only inserting same data multiple times.
why not you check whether the list is empty or not before adding data into it and clear the data if its not empty and then add new.
if(servicesList.isEmpty())
servicesList.add(service);
//else clear and add data
else{
servicesList.clear();
servicesList.add(service);
}
To handle data duplicacy, you can use a Set which will ignore duplicate inserts on scrolling.
servicesList.add(service);
Set<Service> mSet= new HashSet<Service>();
mSet.addAll(servicesList);
servicesList.clear();
servicesList.addAll(mSet);
OR use Set other than ArrayList
little clumsy but will work for you.
I have a custom listView with 200 values coming from Cloud DB. All the values are received properly and added in ArrayList(hotelList). When I am passing to the ArrayList(hotelList) to Custom Adapter class, showing all the values as last element. Many stackOverflow questions found here related to this I tried them too. None worked for me. How should I fix this?
The code is,
#Override
protected void onPostExecute(String result) {
try {
Log.d("Inside Post", "message");
root = new JSONObject(result);
validation = root.getInt("response");
message = root.getString("message");
JSONArray data=root.getJSONArray("data");
data.length();
if(validation==1) {
hgs=new HotelGetSetter();//Getting and setting class
for(int i=0;i<data.length();i++){
hgs.setName(data.getJSONObject(i).getString("hotel_name"));
hgs.setPlace(data.getJSONObject(i).getString("city"));
hotelList.add(hgs);//While Debugging, all the 200 values from db received and added in the ArrayList(hotelList) values also there correctly
}
//But after the loop all the values here changed to last element value(debugged).
mainMethod();
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
public void mainMethod(){
HotelCustomAdapter hca=new HotelCustomAdapter(HotelMaster.this,hotelList);
list_hotel.setAdapter(hca);
//list_hotel.setAdapter(new HotelCustomAdapter(this, hotel_id1,hotel_name1,hotel_place1));
}
you initialize variable hgs=new HotelGetSetter(); out of for loop and then you are always editing the same instance
You are changing the values for the same object hsg through the loop instead of creating different objects for each set of values. Therefore the 200 same objects.
Just move the hgs=new HotelGetSetter(); into the loop and it should work.
I'm trying to populate a ListView with various objects obtained from a RESTApi.
To test if the connection, and the objects are actually recieved, I invoke this method:
protected void onPostExecute(String result) {
try {
JSONArray users = new JSONArray(result);
JSONObject user = users.getJSONObject(1);
Toast.makeText(MainActivity.this, user.getString("name"), Toast.LENGTH_LONG).show();
jsonList = users;
} catch (JSONException e) {
e.printStackTrace();
}
}
The Toast does show me the name of the current object, but whenever I try to populate my ListView, I get a NullPointerException.
I made a TextView to test if the JSON is actually there aswell, but here I get another NullPointerException:
textView.setText(user.getString("name"));
Why does it give me a NullPointer here, when the JSONObject works fine in the Toast?
As far as your code seems
You are accessing the first element of users object
You have to specify list view's first index as well,
you are accessing 1st element and passing to the whole listview
Please follow the basic programming of Listview
http://www.wingnity.com/blog/android-json-parsing-and-image-loading-tutorial/
Create a Bean class with getters and setters then populate the Bean with JSON data and use it as the data source to your listView adapter!
i made a listview with all the posts in the list.
what i want is when i click the child in the list i want another activity to be opened showing that specific post and the related comments
the question is how to know which item is clicked and how to show that particular post ParseObject in next activity
as they do in messaging app in which you click the message from the listview and subsequent messages are shown in the next activity
i might be very thankful to you if you solve this for me!!
Please Try this code:
Please implement your object class with Serializable
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3) {
try
{
Log.v("position",position); // hear is your list item position
MyClass obj = new MyClass(); // Class must be implements with Serializable
Intent showintent = new Intent(context,<activity class to open>);
showcontactintent.putExtra("obj",obj);
startActivity(showintent);
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
Use: Relational Data
Objects can have relationships with other objects. To model this behavior, any ParseObject can be used as a value in other ParseObjects. Internally, the Parse framework will store the referred-to object in just one place, to maintain consistency.
For example, each Comment in a blogging app might correspond to one Post. To create a new Post with a single Comment, you could write:
// Create the post
ParseObject myPost = new ParseObject("Post");
myPost.put("title", "I'm Hungry");
myPost.put("content", "Where should we go for lunch?");
// Create the comment
ParseObject myComment = new ParseObject("Comment");
myComment.put("content", "Let's do Sushirrito.");
// Add a relation between the Post and Comment
myComment.put("parent", myPost);
// This will save both myPost and myComment
myComment.saveInBackground();
You can also link objects using just their objectIds like so:
// Add a relation between the Post with objectId "1zEcyElZ80" and the comment
myComment.put("parent", ParseObject.createWithoutData("Post", "1zEcyElZ80"));
By default, when fetching an object, related ParseObjects are not fetched. These objects' values cannot be retrieved until they have been fetched like so:
fetchedComment.getParseObject("post")
.fetchIfNeededInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject post, ParseException e) {
String title = post.getString("title");
// Do something with your new title variable
}
});
You can also model a many-to-many relation using the ParseRelation object. This works similar to List, except that you don't need to download all the ParseObjects in a relation at once. This allows ParseRelation to scale to many more objects than the List approach. For example, a User may have many Posts that they might like. In this case, you can store the set of Posts that a User likes using getRelation. In order to add a post to the list, the code would look something like:
ParseUser user = ParseUser.getCurrentUser();
ParseRelation<ParseObject> relation = user.getRelation("likes");
relation.add(post);
user.saveInBackground();
You can remove a post from the ParseRelation with something like:
relation.remove(post);
For more read: https://parse.com/docs/android/guide#objects-relational-data
^why did I copy all the words here instead of just providing the link? Because parse links are broken sometimes and doesn't direct you to the section you need (instead it just sends you to https://parse.com/docs/android/guide and because the doc is so large, you won't be able to find it.