I am working on a demo android app. Currently, I have a list of products which I am displaying, but they all have same image and the text generated is also random characters generated with Java method. Needless to say, it doesn't look very good.
I am using an adapter and displaying the data. How can I efficiently use random images(either from URL or from a selected folder), and names from some XML file to make the UI look better.
Code :
public class Products extends Activity{
ProductAdapter productAdapter;
List<Product> productList = new ArrayList<>();
private SecureRandom random = new SecureRandom();
public static final String productName = "productName";
public static final String productComments = "productComments";
public static final String productLikes = "productLikes";
public static final String productDescription = "productDescription";
public static final String userName = "userName";
ListView productsList;
#Override
protected void onCreate(Bundle savedInstanceState) {
for(int i=1;i<100;i++){
Product product = createProduct();
productList.add(product);
}
ArrayList<HashMap<String, String>> productsArrayHashList = new ArrayList<>();
for (Product product : productList){
HashMap<String,String> productDisplay = new HashMap<>();
productDisplay.put(productName,product.getName());
productDisplay.put(productComments,String.valueOf(product.getCommentCount()));
productDisplay.put(productLikes,String.valueOf(product.getLikes()));
productDisplay.put(productDescription,product.getDescription());
productDisplay.put(userName,new BigInteger(130, random).toString(32));
productsArrayHashList.add(productDisplay);
}
productsList = (ListView) findViewById(R.id.productList);
productAdapter = new ProductAdapter(this,productsArrayHashList);
productsList.setAdapter(productAdapter);
}
public Product createProduct(){
int minimum = 1;
int maxValue = 20;
Product product = new Product();
product.setCommentCount(minimum + random.nextInt(maxValue - minimum + 1));
product.setLikes(minimum + random.nextInt(maxValue - minimum + 1));
product.setSaveDate(new Timestamp(System.currentTimeMillis()));
product.setDescription(new BigInteger(130, random).toString(32));
product.setName(new BigInteger(130, random).toString(32));
product.setSize(new BigInteger(130, random).toString(32));
if(getRandomBoolean()) {
product.setSold(true);
}else {
product.setSold(false);
}
return product;
}
Adapter code :
public class ProductAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
private SecureRandom random = new SecureRandom();
public ProductAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = inflater.inflate(R.layout.product_row, null);
TextView productName = (TextView) view.findViewById(R.id.productName);
TextView userUploader = (TextView)view.findViewById(R.id.uploadingUser);
RatingBar ratingBar = (RatingBar)view.findViewById(R.id.productStars);
TextView comments = (TextView) view.findViewById(R.id.comments);
TextView productDetails = (TextView) view.findViewById(R.id.description);
ImageView prodImage = (ImageView) view.findViewById(R.id.productImage);
prodImage.setImageResource(R.drawable.productwatch);
HashMap<String, String> productList;
productList = data.get(position);
productName.setText(productList.get(Products.productName));
comments.setText("Comments("+productList.get(Products.productComments)+")");
productDetails.setText(productList.get(Products.productDescription));
userUploader.setText(productList.get(Products.userName));
int minimum = 1;
int maxValue = 5;
ratingBar.setRating((float) (minimum + random.nextInt(maxValue - minimum + 1)));
}
return view;
}
}
Thank you.
I have a solution.
You'll need Picasso library for Android
Add this line to build.gradle under dependancies
compile 'com.squareup.picasso:picasso:2.5.2'
In your Adapter code, add this after initializing your ImageView.
Picasso.with(getApplicationContext)
.load("http://lorempixel.com/200/200/")
.into(imageView);`
For more info : Picasso - Github
The numbers after that URL are the dimensions, you can specify suitable dimensions.
I used http://lorempixel.com/ (Visit it to explore more features)
You can use any site to get the images.
Related
at first I got an error " The code of method getView(int, View, ViewGroup) is exceeding the 65535 bytes limit " because I typed too much code, finally I created a method, but the method is error because the variable inside is not detected
I created Method _Differ();
public void _Differ() {
if (_position == 5) {
full.setText("iiii");
}
}
i put method Differ(); in custom adapter listview
this is my code in listview custom adapter
public class Listview1Adapter extends BaseAdapter {
ArrayList<HashMap<String, Object>> _data;
public Listview1Adapter(ArrayList<HashMap<String, Object>> _arr) {
_data = _arr;
}
#Override
public int getCount() {
return _data.size();
}
#Override
public HashMap<String, Object> getItem(int _index) {
return _data.get(_index);
}
#Override
public long getItemId(int _index) {
return _index;
}
#Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = getLayoutInflater();
View _view = _v;
if (_view == null) {
_view = _inflater.inflate(R.layout.ccc, null);
}
final LinearLayout linear1 = _view.findViewById(R.id.linear1);
final LinearLayout linear2 = _view.findViewById(R.id.linear2);
final LinearLayout linear3 = _view.findViewById(R.id.linear3);
final LinearLayout linear4 = _view.findViewById(R.id.linear4);
final TextView textview1 = _view.findViewById(R.id.textview1);
final TextView full = _view.findViewById(R.id.full);
final TextView textview2 = _view.findViewById(R.id.textview2);
final TextView shortt = _view.findViewById(R.id.shortt);
final TextView name = _view.findViewById(R.id.name);
final TextView email = _view.findViewById(R.id.email);
full.setText(mapList.get((int)_position).get("end").toString());
shortt.setText(mapList.get((int)_position).get("rule").toString());
email.setText(mapList.get((int)_position).get("start").toString());
_Differ();
return _view;
}
}
//This is your method which will go in your activity >>
public void _Differ(TextView txt, int _position) {
if (_position == 5) {
txt.setText("iiii");
}
}
// This Code Goes in your ListAdpater >>
full.setText(mapList.get((int)_position).get("end").toString());
shortt.setText(mapList.get((int)_position).get("rule").toString());
email.setText(mapList.get((int)_position).get("start").toString());
_Differ(full, _position);
I think this can help you, By the way, Are you using Sketchware Pro đŸ¤”
I am trying to display the Map values in ListView using BaseAdapter. Using the below code I am able to successfully print all the values in Map. But i don't know how to display a single value of Map using its key.
MyContactAdapter2.java
public class MyContactAdapter2 extends BaseAdapter {
List<EffectList> contacts;
Context context;
private LayoutInflater mInflater;
// Constructors
public MyContactAdapter2(Context context, List<Map<String, List<EffectList>>> objects) {
this.context = context;
this.mInflater = LayoutInflater.from(context);
this.contacts = new ArrayList<>();
Map<String, List<EffectList>> map = objects.get(0);
Set<String> keySet = map.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()) {
this.contacts.addAll(map.get(iterator.next()));
}
}
#Override
public int getCount() {
int count = contacts.size();
return count;
}
#Override
public EffectList getItem(int position) {
return contacts.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final MyContactAdapter2.ViewHolder vh;
if (convertView == null) {
View view = mInflater.inflate(R.layout.get_layout_row_view, parent, false);
vh = MyContactAdapter2.ViewHolder.create((RelativeLayout) view);
view.setTag(vh);
} else {
vh = (MyContactAdapter2.ViewHolder) convertView.getTag();
}
EffectList item = getItem(position);
vh.textViewName.setText(item.getEffectsId());
vh.textViewEmail.setText(item.getEffectsName());
return vh.rootView;
}
private static class ViewHolder {
public final RelativeLayout rootView;
public final ImageView imageView;
public final TextView textViewName;
public final TextView textViewEmail;
private ViewHolder(RelativeLayout rootView, ImageView imageView, TextView textViewName, TextView textViewEmail) {
this.rootView = rootView;
this.imageView = imageView;
this.textViewName = textViewName;
this.textViewEmail = textViewEmail;
}
public static MyContactAdapter2.ViewHolder create(RelativeLayout rootView) {
ImageView imageView = (ImageView) rootView.findViewById(R.id.imageView);
TextView textViewName = (TextView) rootView.findViewById(R.id.textViewName);
TextView textViewEmail = (TextView) rootView.findViewById(R.id.textViewEmail);
return new MyContactAdapter2.ViewHolder(rootView, imageView, textViewName, textViewEmail);
}
}
}
This is the Json I need to parse,
{
"effect_list": [{
"1":[
{
"effects_id":"1",
"effects_name":"Band 1"
},
{
"effects_id":"2",
"effects_name":"Band 2"
}
],
"2": [
{
"effects_id":"4",
"effects_name":"Background Blur"
},
{
"effects_id":"5",
"effects_name":"Blemish Removal"
}
]
}]
}
I want to display only the values of "1" ("effects_id":"1","effects_name":"Band 1" and "effects_id":"2","effects_name":"Band 2"). How can I achieve it?
I am confused with the code inside constructor too. If you can,Please explain the following code,
this.contacts = new ArrayList<>();
Map<String, List<EffectList>> map = objects.get(0);
Set<String> keySet = map.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()) {
this.contacts.addAll(map.get(iterator.next()));
EDIT
EffectList.java
public class EffectList {
#SerializedName("effects_id")
#Expose
private String effectsId;
#SerializedName("effects_name")
#Expose
private String effectsName;
public String getEffectsId() {
return effectsId;
}
/* public void setEffectsId(String effectsId) {
this.effectsId = effectsId;
}
*/
public String getEffectsName() {
return effectsName;
}
/*
public void setEffectsName(String effectsName) {
this.effectsName = effectsName;
}
*/
}
You are getting objects as List<Map<String, List<EffectList>>> therefore you are doing a get on the first index to get the first map in the list.
Afterwards you are retrieving the key set of your map, this is a Set which contains all keys that are available in your map.
The iterator is used to retrieve the corresponding List from your map to each key that your map contains.
You could optimize this a bit by doing following:
Set<List<EffectList>> values = map.values;
Iterator<List<EffectList>> it = values.iterator();
while(it.hasNext() {
this.contacts.addAll(it.next());
}
To archive the desired output you could filter the EffectList before adding this to the contacts list.
EDIT
As example(using google commons collections):
List<EffectList> itValue = it.next();
List<EffectList> filteredValue = Collections.filter(itValue, new Predicate<EffectList>(){
public boolean apply(EffectList input){
if(input.getEffectsId().equals("1") || input.getEffectsId().equals("2"){
return true;
}
return false;
}
);
this.contacts.addAll(filteredValue);
I am working on an Android app, in which the user uploads a photo. Now, I am calling a method from the server, which will return me a list of users. I would like to display this list along with the photos.
The images stored in the server are in byte-array. So I am converting them to String and then to Bitmap for showing. Unfortunately, it is not working as I am doing stuff with a Adapters as well. The image retrieved in adapter class is null. What am I doing wrong?
OtherUsers.java :
public class OtherUsers extends Activity {
private PersonServiceImpl personService = new PersonServiceImpl();
private static volatile List<RestPerson> restPersonList = new ArrayList<>();
public static final String firstName = "firstname";
public static final String userImage = "userimage";
static final Long userId = (long)0;
ListView listView;
UserAdapter userAdapter;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.displayuserlist);
restPersonList = this.personService.getOtherUsers();
// Base64 base64Encoder = new Base64();
ArrayList<HashMap<String, String>> usersArrayHashList = new ArrayList<>();
for(RestPerson restPerson : restPersonList){
HashMap<String, String> restDisplay = new HashMap<>();
restDisplay.put("userId",String.valueOf(restPerson.getUserId()));
restDisplay.put("firstName",restPerson.getFirstName());
restDisplay.put("userImage","data:image/png;base64," + Base64.encode(restPerson.getProfilePhoto()));
usersArrayHashList.add(restDisplay);
}
listView = (ListView) findViewById(R.id.usersdisplaylist);
userAdapter = new UserAdapter(this,usersArrayHashList);
listView.setAdapter(userAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Long userid = restPersonList.get(position).getUserId();
Log.d("Userid is ", String.valueOf(userid));
}
});
UserAdapter class :
public class UserAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
public UserAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.userprofiles, null);
TextView username = (TextView) view.findViewById(R.id.userName);
ImageView userImage = (ImageView) view.findViewById(R.id.userImage);
HashMap<String, String> usersList = new HashMap<>();
usersList = data.get(position);
username.setText(usersList.get(OtherUsers.firstName));
String image = usersList.get(OtherUsers.userImage);
Log.d("Image is ",image);
byte[] newImageBytes = image.getBytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(newImageBytes,0,newImageBytes.length);
userImage.setImageBitmap(bitmap);
userImage.setImageBitmap(null);
return view;
}
}
If there is any other information required, kindly let me know. Thanks.
Update
Sorry, forgot to put LogCat
08-24 13:43:16.618 29948-29948/internetlegion.com.gradlecheck E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: internetlegion.com.gradlecheck, PID: 29948
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:139)
at internetlegion.com.gradlecheck.Adapters.UserAdapter.getView(UserAdapter.java:62)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
at android.widget.ListView.onMeasure(ListView.java:1182)
at android.view.View.measure(View.java:17547)
data struct that you have used in adapter is very strange. it's better to create one class with three property and send one list of those to adapter class.
any way, your problem is :
public static final String userImage = "userimage";
you define userImage with value userimage, then you insert into hashmap with "userImage" that is not equal with value of userImage ( value have lower case i) then you have try to get "userimage" from hashmap that is not exists, so value is null.
Answer:
you can change following line:
restDisplay.put("userImage","data:image/png;base64," + Base64.encode(restPerson.getProfilePhoto()));
to
restDisplay.put(userImage,"data:image/png;base64," + Base64.encode(restPerson.getProfilePhoto()));
but better way is create custom object.
I am writing food ordering program, and in CartActivity i have to show Grand Total of all items available in Cart.
Here is How my CartActivity looks right now :
As you can see i am using a TextView above ListView, which has 0.00 as default value, here i want to show Total of all list items....
Can someone help me ? because i believe many of you already experienced this
CartActivity.java:-
public class CartActivity extends Activity{
ListView listView;
CartAdapter cartAdapter;
TextView textGrandTotal;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
listView = (ListView) findViewById(R.id.listViewCart);
textGrandTotal = (TextView) findViewById(R.id.textGrandTotal);
cartAdapter = new CartAdapter(CartActivity.this);
listView.setAdapter(cartAdapter);
if(Handler.itemsHandler.size()>0)
{
for (int i = 0; i < Handler.itemsHandler.size(); i++) {
}
}
}
}
CartAdapter.java:-
public class CartAdapter extends BaseAdapter {
// Declare Variables
Context context;
LayoutInflater inflater;
HashMap<String, String> resultp = new HashMap<String, String>();
public CartAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return Handler.itemsHandler.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// Declare Variables
public View getView(final int position, View convertView, ViewGroup parent) {
// Declare Variables
final ViewHolder holder;
if(convertView==null)
{
holder = new ViewHolder();
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.adapter_cart, null);
// Locate the TextViews in listview_item.xml
holder.title = (TextView) convertView.findViewById(R.id.textTitle);
holder.cost = (TextView) convertView.findViewById(R.id.textCost);
holder.total = (TextView) convertView.findViewById(R.id.textTotal);
holder.quantity = (TextView) convertView.findViewById(R.id.editQuantity);
holder.add = (ImageButton) convertView.findViewById(R.id.btnAdd);
holder.less = (ImageButton) convertView.findViewById(R.id.btnLess);
holder.quantity.setText("1");
holder.quantity.setEnabled(false);
HashMap<String, String> item = new HashMap<String, String>();
item = Handler.itemsHandler.get(position);
// Capture position and set results to the TextViews
holder.title.setText(item.get(ItemActivity.OBJECT_TITLE));
holder.cost.setText(item.get(ItemActivity.OBJECT_COST));
Log.d("Getting Handler", "Item [getting]:: " + item);
String strValue = holder.quantity.getText().toString();
Log.d("quantity::", strValue);
int newValue = Integer.parseInt(strValue);
Log.d("newValue", String.valueOf(newValue));
String strCost = holder.cost.getText().toString();
Log.d("cost::", strCost);
double costValue = Double.parseDouble(strCost);
Log.d("double::cost:-", String.valueOf(costValue));
holder.total.setText(new DecimalFormat("##.#").format(costValue*newValue));
String total = holder.total.getText().toString();
Log.d("total::", total);
..........
return convertView;
}
}
Handler.java:-
public class Handler {
public static ArrayList<HashMap<String, String>> itemsHandler = new ArrayList<HashMap<String, String>>();
}
public class CartActivity extends Activity{
ListView listView;
CartAdapter cartAdapter;
TextView textGrandTotal;
double sum=0;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
listView = (ListView) findViewById(R.id.listViewCart);
textGrandTotal = (TextView) findViewById(R.id.textGrandTotal);
cartAdapter = new CartAdapter(CartActivity.this);
listView.setAdapter(cartAdapter);
if(Handler.itemsHandler.size()>0)
{
for (int i = 0; i < Handler.itemsHandler.size(); i++) {
HashMap<String, String> item = new HashMap<String, String>();
item = Handler.itemsHandler.get(position);
String strCost= item.get(ItemActivity.OBJECT_COST);
//add this line of code
String quantity= item.get(ItemActivity.OBJECT_QUANTITY);
double costValue = Double.parseDouble(strCost*quantity);
sum=sum+costValue;
}
}
}
}
you just have to multiply (cost of each item*number of items) like above i did.
I know this question has been asked thousands of times but I couldn't find an answer for my case for some reason.
What I have is a thread that fetches data from a web services and populates a list with the info. Then I want to press a button and call the same thread to fetch some more data and add it to the list.
But when I call notifyDataSetChanged(), the list for some reason doesn't refresh. The data is in the adapter though...
Here's the code:
#Override
protected void onPostExecute(PropertyNotesParser result) {
this.progressDialog.dismiss();
ArrayList<PropertyNoteHistory> propertyNoteList = result.getAllTheNotes();
addNoteListItems(propertyNoteList);
Collections.sort(getNoteList());
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> subtitles = new ArrayList<String>();
DateHandler handleDate = new DateHandler();
DataResolve convert = new DataResolve();
for(Iterator<PropertyNoteHistory> i = getNoteList().iterator(); i.hasNext(); ) {
PropertyNoteHistory item = i.next();
PropertyNoteHistory.Note note = item.getNotes();
PropertyNoteHistory.Jobs jobs = item.getJobs();
// Default value is office in case the xml does not have the tag "job" associated with "note".
String service = "Office";
if(jobs != null){
service = convert.getServiceName(jobs.getServiceID());
}
titles.add(note.getTitle() + " (" + service + ")");
subtitles.add(handleDate.formatDate(note.getDate(), "dd MMM yyyy") + " Ref: " + note.getJobID());
}
if(getConnectionCount() == 0){
adapter = new SimpleListAdapter(getActivity(), titles, subtitles);
lv.setAdapter(adapter);
}
else {
adapter.addItem(titles, subtitles);
}
and my adapter:
public class SimpleListAdapter extends BaseAdapter {
private int count = 0;
private static LayoutInflater inflater = null;
private ArrayList<String> titles = new ArrayList<String>();
private ArrayList<String> subtitles = new ArrayList<String>();
private ArrayList<Integer> imageResource = new ArrayList<Integer>();
private boolean hasImage = false;
public SimpleListAdapter(Activity activity, ArrayList<String> titles,
ArrayList<String> subtitles, ArrayList<Integer> imageResource) {
count = titles.size();
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.titles = titles;
this.subtitles = subtitles;
this.imageResource = imageResource;
this.hasImage = true;
}
/**Constructor that creates an adapter with only a title and subtitle.
* #param activity The context.
* #param titles ArrayList with the titles of each list option.
* #param subtitles ArrayList with the subtitles of each list option. */
public SimpleListAdapter(Activity activity, ArrayList<String> titles,
ArrayList<String> subtitles) {
count = titles.size();
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.titles = titles;
this.subtitles = subtitles;
this.hasImage = false;
}
public void addItem(ArrayList<String> title, ArrayList<String> subtitle){
this.titles.addAll(title);
this.subtitles.addAll(subtitle);
notifyDataSetChanged();
}
#Override
public int getCount() {
return count;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v == null)
v = inflater.inflate(R.layout.layout_simple_list, null);
final ImageView icon = (ImageView) v.findViewById(R.id.icon);
final TextView title = (TextView) v.findViewById(R.id.title);
final TextView subtitle = (TextView) v.findViewById(R.id.subtitle);
title.setText(titles.get(position));
subtitle.setText(subtitles.get(position));
if (hasImage) {
icon.setImageResource(imageResource.get(position));
}
else {
icon.setVisibility(ImageView.GONE);
}
return v;
}
}
You will need to update your count variable too in addItem so that the all the rows are created when notifyDataSetChanged is called