Display a single object in layout from JSON - android

I feel silly asking this, but how do I display a single object in an android layout after obtaining it's data from JSON? I know how to display data in a listview, but haven't learned how to display a single object. Do I need any kind of adapter?
Here's how I parse the data from Volley (I'm aware of libraries like Jackson and GSON):
public void parseDeal(JSONObject response) {
Deal dealItem = new Deal();
try {
dealItem.setId(response.getInt("id"));
dealItem.setHeadline(response.getString("headline"));
dealItem.setTimeStamp(response.getString("created_at"));
dealItem.setImge(response.getString("image_url"));
JSONObject mVendor = response.getJSONObject("vendor");
dealItem.setVendorPic(mVendor.getString("image_url"));
// how to adapt to the view?
} catch (JSONException e) {
e.printStackTrace();
}
}
There are certain JSON attributes in the object that may come back null, so I want to be able to handle those by changing their visibility in the view conditionally. I have done that in a list adapter before like this, but not sure if I need an adapter in this case:
if (!TextUtils.isEmpty(item.getHeadline())) {
headlineMsg.setText(item.getHeadline());
headlineMsg.setVisibility(View.VISIBLE);
} else {
// status is empty, remove from view
headlineMsg.setVisibility(View.GONE);
}
UPDATE
Here is my Deal object class.
public class Deal {
private int id;
private String headline, image, vendorPic, timeStamp;
public Deal() {
}
public Deal(int id, String image, String headline,
String vendorPic, String timeStamp) {
super();
this.id = id;
this.image = image;
this.headline = headline;
this.vendorPic = vendorPic;
this.timeStamp = timeStamp;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImge() {
return image;
}
public void setImge(String image) {
this.image = image;
}
public String getHeadline() {
return headline;
}
public void setHeadline(String headline) {
this.headline = headline;
}
public String getVendorPic() {
return vendorPic;
}
public void setVendorPic(String vendorPic) {
this.vendorPic = vendorPic;
}
public String getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(String timeStamp) {
this.timeStamp = timeStamp;
}
}

I think i can follow you're logic here. You should work on implementing a rendering class. This is called upon the loading of the visual component that holds all this information. The renderer should turn on and off the views that are not null. The rendering class is the actual code that takes the data you have pulled out of the json, checks it to make sure there is data actually there (not null) and sets the required view to the desired value.
if (dealItem.getTimeStamp() != null && dealItem.getTimeStamp() != "") {
LayoutView.setText(dealItem.getTimeStamp()));
LayoutView.setVisibility(View.VISIBLE);
} else {
// status is empty, remove from view
LayoutView.setVisibility(View.GONE);
}

Why don't you simply create a Fragment or activity with TextViews (or whatever view you prefer...) ?
You don't need an adapter for that. Then you simply populate it on onCreate (activity) or fragment (onViewCreated) with the values from the object !
Hope it helps !

Related

How to change the data of an item at once using DiffUtil?

When I press the toggle button, I want to change the units of the list of the currently displayed recycler views at once.
I used ListAdapter + DiffUtil to display the recycler view.
The way I tried to implement this feature is to load the current list when the toggle button is pressed.
Then, after resetting the new toggle unit values ​​for the current lists, I used submitList() to update the list.
But this was the wrong way.
My guess is because the variable created for the value of the list loaded to be updated has the same reference value, so the value changed at the same time.
In other words, there is no change because the values ​​of the update list and the existing list are the same.
What can I do to solve this problem?
RoutineDetailModel.java
public class RoutineDetailModel {
public int id;
private int set = 1;
public static String unit = "kg";
public RoutineDetailModel() {
Random random = new Random();
this.id = random.nextInt();
}
public RoutineDetailModel(int set) {
Random random = new Random();
this.id = random.nextInt();
this.set = set+1;
}
public int getSet() {
return set;
}
public int getId() {
return id;
}
public String getWeight() {
return weight;
}
public String getUnit() {
return unit;
}
#Override
public int hashCode() {
return Objects.hash(set, weight); // getWeight를 호출하면 더 다양하게 되나?
}
#Override
public boolean equals(#Nullable Object obj) {
if(obj != null && obj instanceof RoutineDetailModel) {
RoutineDetailModel model = (RoutineDetailModel) obj;
if(this.id == model.getId()) {
return true;
}
}
return false;
}
}
MainActivity.java
public class WriteRoutineActivity extends AppCompatActivity implements WritingCommentDialogFragment.OnDialogClosedListener {
List<RoutineModel> items;
RoutineListAdapter listAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_write_routine);
listAdapter.setOnRoutineClickListener(new RoutineListAdapter.OnRoutineItemClickListener() {
#Override
public void onUnitBtnClicked(int curRoutinePos, String unit) {
Object obj = listAdapter.getRoutineItem(curRoutinePos);
RoutineModel item = (RoutineModel) obj;
if(obj instanceof RoutineModel) {
for(RoutineDetailModel detailItem : item.getDetailItemList()) {
detailItem.setUnit(unit);
}
listAdapter.submitList(getUpdatedList());
}
}
});
}
}
Please tell me if you need more information
To change all the items you need to use notifyDataSetChanged() otherwise you cannot update ALL the items.
In order to do so, you must create a method inside your adapter which does the following ->
public void updateItems(String unit) {
for({YOUR ITEM TYPE} item: {YOUR LIST}) {
item.unit = unit;
}
notifyDataSetChanged();
}
And call this method when you want to change all units.
yourAdapter.updateItems("Kg");

how to remove java.lang.numberformatexception: invalid double: ""

I have a method to get all the items in the database, but I don't know what is the problem, it always say java.lang.numberformatexception: invalid double: "". Any help would be highly appreciated.
My code:
#Override
public void processFinish(String s) {
productList = new JsonConverter<Products>().toArrayList(s, Products.class);
BindDictionary dic = new BindDictionary();
dic.addStringField(R.id.tvName, new StringExtractor<Products>() {
#Override
public String getStringValue(Products item, int position) {
return item.name;
}
});
dic.addStringField(R.id.tvDesc, new StringExtractor<Products>() {
#Override
public String getStringValue(Products item, int position) {
return item.description;
}
}).visibilityIfNull(View.GONE);
dic.addStringField(R.id.tvPrice, new StringExtractor<Products>(){
#Override
public String getStringValue(Products item, int position) {
return ""+item.price;
//return String.valueOf(item.price);
}
});
dic.addDynamicImageField(R.id.ivImage, new StringExtractor<Products>() {
#Override
public String getStringValue(Products item, int position) {
return item.img_url;
}
}, new DynamicImageLoader() {
#Override
public void loadImage(String url, ImageView img) {
//Set image
ImageLoader.getInstance().displayImage(url, img);
}
});
}
Products.java
public class Products implements Serializable {
#SerializedName("itemID")
public int id;
#SerializedName("productName")
public String name;
#SerializedName("descrt")
public String description;
#SerializedName("price")
public double price;
#SerializedName("my_img")
public String img_url;
}
Thanks in advance.
This error because of your Products.java
There is a double type property in your Products.java that called price,
When you convert the json object to java object the both types must be same. In your case,
you get a
{
...
price:"",
....
}
in your json object. But the java side, it waits for double value. You could send price:0.0 instead of price:"" or write your own converter.
first see the datatype for price which you want to send.i also faced same situation long back i resolved it by passing data what is expected or before sending data parse the data to required type.
#Override
public double getStringValue(Products item, int position) {
return ""+item.price;
//return String.valueOf(item.price);
}

Android Studio displaying FirebaseListAdapter change codes

i have a FirebaseListAdapter which retrieves all the uid from the user but i want it to retrieve the names instead.
i have two child. one is to store all the uid of the connected users for a chat, and the other contains their information such as names. how do i convert the retrieved values (uid) into names and display it as shown below.
i have attached a snippet of how my app looks like currently and i want it to show names instead of uid.
FirebaseListAdapter<String> firebaseListAdapter = new FirebaseListAdapter<String>(getActivity(), String.class, R.layout.fragment_chatfprow, mDatabase) {
#Override
protected void populateView(View v, String model, int position) {
TextView text = v.findViewById(R.id.text1);
text.setText(model);
}
};
i think there is something to do with these lines of code but i cant figure out how.
This is how my Firebase ListView looks like
You need a model class for Firebase UI Database with an empty constructor for example:
public class Users {
private String mName;
private String mMessage;
public Users() {} // Required for Firebase
public Users(String name, String message) {
mName = name;
mMessage = message;
}
public String getName() { return mName; }
public void setName(String name) { mName = name; }
public String getMessage() { return mMessage; }
public void setMessage(String message) { mMessage = message; }
}
Then in Adapter creation you can do like this:
FirebaseListAdapter<Users> firebaseListAdapter = new FirebaseListAdapter<Users>(getActivity(), Users.class, R.layout.fragment_chatfprow, mDatabase) {
#Override
protected void populateView(View v, String model, int position) {
TextView text = v.findViewById(R.id.text1);
text.setText(model.getName());
}
};
You can take a look here from more informations: https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md

How to autocomplete text in a textview with firebase database in an android app

I want something like below image. Image is of autocomplete search from firebase website itself.
I've seen many post about this, but those posts does not seem to work with firebase above 3.0.
I want to search in an autcomplete textview either with entering name or number. Here's an entry from my database
In short, it should suggest entries from my firebase database as I start typing.
One solution for achieving this would be loading your data from the realtime database into an ArrayList before you start searching.
So to do this first you'll need to check when the Firebase Listener
is done retrieving your data from the database. Firebase Listeners are not executed in sequence and the ValueListener is always executed last. So you can do something like retrieve your data through a ChildListener and then execute to ValueListener to make sure the data is completely retrieved rootRef.addListenerForSingleValueEvent()
Later when your data is retrieved and stored in a arraylist you can follow this to add the search functionality
Hope it helps!
First of all add the required dependencies of firebase and glide or other dependency for image view in build.gradle .
Create a reference for the tree as follows
mUserDatabase = FirebaseDatabase.getInstance().getReference("YourTreeRootNameHere");
Pass the string in the text field with a onTextChanged method to the following function firebaseUserSearch. Make necessary changes in the following function according to your code.
private void firebaseUserSearch(String searchText) {
Query firebaseSearchQuery = mUserDatabase.orderByChild("sName").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerAdapter<Users, SearchActivity.UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, SearchActivity.UsersViewHolder>(
Users.class,
R.layout.list_layout,
SearchActivity.UsersViewHolder.class,
firebaseSearchQuery
) {
#Override
protected void populateViewHolder(SearchActivity.UsersViewHolder viewHolder, final Users model, final int position) {
viewHolder.setDetails(getApplicationContext(), model.getName(), model.getPlace(), model.getImage());
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
// View Holder Class
public static class UsersViewHolder extends RecyclerView.ViewHolder {
View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context ctx, String userName, String userStatus, String userImage){
TextView user_name = (TextView) mView.findViewById(R.id.name_text);
TextView user_status = (TextView) mView.findViewById(R.id.status_text);
ImageView user_image = (ImageView) mView.findViewById(R.id.profile_image);
user_name.setText(userName);
user_status.setText(userStatus);
Glide.with(ctx).load(userImage).into(user_image);
}
}
Create your layout for recyclerView and define the data model class. For example this function uses a Users.class that is shown below.
public class Users {
public String name, image, place;
public Users(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getPlace() {
return place;
}
public void setPlace(String status) {
this.place = status;
}
public Users(String name, String image, String place) {
this.name = name;
this.image = image;
this.place = place;
}
}

Realm: How to query with many to many field

I recently heard about Realm for android (also available for iOS) in this talk by Joaquim Verques . Very interesting and very powerful tool for persistent data.
I decided to give it a try after the video, researching and reading the documentation.
I found it very easy to use and set up but i end up stuck in the middle of my project because i couldn't manage to successfully make a query with many to many relationships.
I have created a small example for this topic.
My models:
public class Feed extends RealmObject {
#PrimaryKey
private int id;
private String title;
private String description;
private String link;
private Terms terms;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Terms getTerms() {
return terms;
}
public void setTerms(Terms terms) {
this.terms = terms;
}
}
public class Terms extends RealmObject {
private String tag;
private RealmList<Category> categories;
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public RealmList<Category> getCategories() {
return categories;
}
public void setCategories(RealmList<Category> categories) {
this.categories = categories;
}
}
public class Category extends RealmObject {
#PrimaryKey
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
So far so good, now im going to save a list of feeds to realm (make it persistent) and then try to make some query.
public static void test(final Context context,final List<Feed> feedList) {
Realm realm = null;
try {
realm = Realm.getInstance(context);
realm.beginTransaction();
realm.copyToRealmOrUpdate(feedList);
realm.commitTransaction();
RealmResults<Feed> realmResults = realm.where(Feed.class).findAll();// return me all feeds
RealmResults<Feed> realmResults1 = realm.where(Feed.class).equalTo("id", 1).findAll(); // return feed with id 1
RealmResults<Feed> realmResults2 = realm.where(Feed.class).equalTo("terms.tag", "tech").findAll(); // return feeds //with tag = "tech"
RealmResults<Feed> realmResults3 = realm.where(Feed.class).equalTo("terms.category.name", "test").findAll(); //exception here
}
} catch (Exception e) {
//Empty
Log.d("Test","",e);
} finally {
if (realm != null)
realm.close();
}
}
}
Everything run well untill the last query and i get this exception:"java.lang.IllegalArgumentException: Invalid query: category does not refer to a class."
So my question is How do i do that kind of query successfully, as i will like realm to return me every feed with terms which has at least 1 category with name = "test"
Thank you very much
Your field is called "categories" and not "category". The third query should be:
RealmResults<Feed> realmResults3 = realm.where(Feed.class).equalTo("terms.categories.name", "test").findAll();

Categories

Resources