I'm trying to fill a gridview dynamically with icons. I Followed the gridview hello tutorial. However the array with the images is not always exactly the same. Depending on the action before, a different image array is given (extracted from soap response), which is constituted of the icon names, e.g. agenda => agenda.png. I wanted to create the array by looping through the array and adding it with R.drawable + icon_name. However R.drawable is not able to parse to the requested Integer array.
public class ImageAdapter extends BaseAdapter
{
private Context mContext;
final ArrayList<String> image = getIntent().getStringArrayListExtra("image");
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return icoontjes.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public ArrayList<Integer> icoontjes;
{
for (int i=0; i<image.size(); i++){
Integer icon= Integer.valueOf("R.drawable."+image.get(i));
icoontjes.add(icon);
}
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(icoontjes.get(position));
return imageView;
}
}
You can use
for (int i=0; i < image.size(); i++) {
Integer icon = getResources().getIdentifier(image.get(i), "drawable", "your.package");
icoontjes.add(icon);
}
where your.package is the base package of your android application (the package in which you have your static final R class defined.
This way the icon variable will hold the id of your drawable based on your image.get(i).
i can give u an answer but you shouldn't (really shouldn't) do this ...
instead of
Integer icon= Integer.valueOf("R.drawable."+image.get(i));
try
R.class.getField("R.drawable."+image.get(i)).getInt(null)
Related
What pattern do I have to use, if I have ListView in which ImageView and like 500 different icons that could be set on that ImageView. Should I just write If/Switch statement, or there is another way/pattern to do it?. Thanks in advance!
Let me assume that you know what icon(I mean the name of icon) to be loaded into the imageView and those icons are available in your drawable resource folder. In this case
#Override
public void onBindViewHolder(final RecyclerAdapter.ViewHolder holder, int position) {
DataItem dataItem = dataList.get(holder.getAdapterPosistion());
try {
int resID = activityContext.getResources().getIdentifier(dataItem.getIconName() , "drawable"/**resource folder name*/, activityContext.getPackageName());
holder.imageView.setBackgroundResource(resID);
} catch (Exception e) {
throw new RuntimeException("Error getting Resource ID.", e)
}
}
Where are these icons that you want to set? you are getting them from server or they are stored locally in your application file? or they are from user phone gallery?
Here is the code you want for your adapter:
public class MyAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
private ArrayList<String> mIconNames;
public MyAdapter(Context context) {
mContext = context;
mIconNames = getIconNames();
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mIconNames.size();
}
#Override
public Object getItem(int position) {
return mIconNames.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get view for row item
View rowView = mInflater.inflate(R.layout.your_layout, parent, false);
ImageView thumbnailImageView =
(ImageView) rowView.findViewById(R.id.your_image_view_id);
Picasso.with(mContext).load(mIconNames.get(position)).placeholder(R.mipmap.ic_launcher).into(thumbnailImageView);
return rowView;
}
//this method builds your icon names
private ArrayList<String> getIconNames() {
ArrayList<String> iconNames = new ArrayList<>();
int numberOfIcons = 99;
String iconBaseName = "icon";
for (int i = 1; i < numberOfIcons; i++) {
iconNames.add(iconBaseName + i);
}
return iconNames;
}
}
I am trying to display detailed Product information in an custom Listview with two TextViews per row for the key/value pair. The data is displayed correct. I also colored every second line different.
And there is my Problem. If I scroll up and down the different colored rows change their color and remain in this state. The data is not affected from this problem. Just the backroundcolor of the TextViews. I use the ViewHolder Pattern but this did not change anything. I added the code of the adapter. I think thats enough. Have you any idea?
Screenshot of the problem:
Code:
public class ProductDetailAdapter extends BaseAdapter {
private LinkedHashMap<String,String> list;
private Context context;
public ProductDetailAdapter(Context c, LinkedHashMap<String,String> list){
super();
this.context = c;
this.list=list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ProductDetailAdapter.ViewHolder viewHolder;
if(convertView == null){
convertView=inflater.inflate(R.layout.product_detail_data_row,null);
viewHolder = new ViewHolder();
viewHolder.textViewKey = (TextView) convertView.findViewById(R.id.productDataKey);
viewHolder.textViewValue = (TextView) convertView.findViewById(R.id.productDataValue);
convertView.setTag(viewHolder);
}else {
viewHolder = (ProductDetailAdapter.ViewHolder) convertView.getTag();
}
viewHolder.textViewKey.setText((String)list.keySet().toArray()[position]);
viewHolder.textViewValue.setText(list.get(list.keySet().toArray()[position]));
if(position % 2 == 0){
viewHolder.textViewKey.setBackgroundColor(context.getResources().getColor(R.color.colorParkerWhite2));
viewHolder.textViewValue.setBackgroundColor(context.getResources().getColor(R.color.colorParkerWhite2));
}
return convertView;
}
private static class ViewHolder {
public TextView textViewKey;
public TextView textViewValue;
public ViewHolder(){};
}
}
That happens because the rows are being recycled. It's a common problem.
You can solve it by doing:
if(position % 2 == 0){
viewHolder.textViewKey.setBackgroundColor(context.getResources().getColor(R.color.colorParkerWhite2));
viewHolder.textViewValue.setBackgroundColor(context.getResources().getColor(R.color.colorParkerWhite2));
} else {
viewHolder.textViewKey.setBackgroundColor(context.getResources().getColor(R.color.colorParkerWhite1)); //Or the color that you want for odd rows
viewHolder.textViewValue.setBackgroundColor(context.getResources().getColor(R.color.colorParkerWhite1)); //Or the color that you want for odd rows
}
Try this:
super( c, 0, list );
instead of this:
super();
Once you pass the data source to the adapter you no longer need :
getCount
getItem
getItemId
please refer this link and link2 and link3 these will work for you
I'm reading in places that it's necessary to have a main method in each class like this:
public static void main(String args [ ]) { }
However, none of my classes in my current project contain such a method, and so far my app experiences no issues...here's one of my classes for reference.
public class GridAdapter extends BaseAdapter {
private final String[] classes = {"Database"}; // Sets the labels for each button
private Context mContext;
public GridAdapter(Context c) {
mContext = c;
}
public int getCount() { //autogenerated tab, returns length of an array.
return mThumbIds.length;
}
// The position an item is in in an array.
public Object getItem(int position) {
return mThumbIds[position];
}
// Gets the ID of each item in the array.
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) { // if it's not recycled, initialize some attributes
gridView = new View(mContext);
gridView = inflater.inflate(R.layout.gridset, null);
TextView textView = (TextView) gridView
.findViewById(R.id.label);
textView.setText(classes[position]);
ImageView imageView = (ImageView) gridView
.findViewById(R.id.img);
imageView.setImageResource(mThumbIds[position]);
} else {
gridView = convertView;
}
return gridView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.img};
}
Is it because I'm extending something (in this case BaseAdapter)? Right now the classes that are currently complete and actually function have an extension, So I am wondering if my WIP classes that don't will need a main() method.
Your reference reads "in at least one class" and pertains to a standalone Java SE program.
In Android you, however, do not need main at all. Your Activities will be brought to life by Android OS calling callbacks into your Activities such as onCreate, onPause etc...
I have a grid view that loads all the images from a specific folder into itself. I'm trying to get it so that when a user click an individual image within the grid view it sets an enlarged version of itself within an image view. I think what I need to try and do is when the grid view is created and the images loaded into it, I need to attach an array to both the imageview created holding the image within the gridview and the location of it within the SD card. So when an image is loaded; save location of image and attach it to the imageview within gridview. What I have so far loads the last picture loaded from the SD card into the enlarged image view.
Main.java
public class Main extends Activity{
ImageView photoHolder;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery);
photoHolder = (ImageView) findViewById(R.id.photoHolderView);
photoHolder.setVisibility(View.GONE);
GridView gridView = (GridView) findViewById(R.id.grid_view);
gridView.setVisibility(View.VISIBLE);
gridView.setAdapter(new ImageAdapter(this));
gridView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> a, View view, int position, long id) {
photoHolder.setVisibility(View.VISIBLE);
photoHolder.setImageURI(ImageAdapter.uri);
}
});
}
}
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
public static Uri uri;
private Context mContext;
File root = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Custom" + File.separator);
private File[] fileName = root.listFiles();
int count = fileName.length;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return fileName.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
uri = Uri.fromFile(fileName[position]);
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some
// attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageURI(uri);
return imageView;
}
}
On a side note it crashes quite a lot due to memory leaks, any idea how I would create a "sample/thumbnail" size image whilst loading it from the SD card?
You are right in stating that you need to keep track of the filenane/location for each of the thumbnail. The easiest way would be to amend your getView method and add one line:
imageView.setImageURI(uri);
imageView.setTag(uri); //new line added
return imageView;
Then, in your onItemClickListener you get the clicked imageview - and get its tag - that will be the filename on the SD card:
public void onItemClick(AdapterView<?> a, View view, int position, long id) {
photoHolder.setVisibility(View.VISIBLE);
photoHolder.setImageURI((Uri)view.getTag());
}
As for the memory issue when loading the bitmap, you can use BitmapFactory.Options to indicate the scaling factor - have a look at this page on Android developer website - it contains the sample code you need.
I want to create an array which contains number of images. Later on I have to use that array in a loop in my code. Can anyone suggest if I can create an array of images.?
define a array of image id like this
int[] p = {R.drawable.image1, R.drawable.image2....}
now for different condition use member of this array like
yourbutton.setBackgroundResource(p[0]) // or p[1]
or you can use ENUM to make it more readable..
this will solve you problem:
int imageArray[] = new int[number_of_images];
for (int i = 0; i < numImages; i++)
imageArray[i] = getDrawableId(getApplicationContext(),"R.drawable." + image_names[i]);
You can define an array of image filenames :
String fileNames[] = {"temp.jpg", "sample_img28.jpg", "normImg.jpg", "drawing.png", "film.png"};
and add those in MeidaTracker while initializing the application
MediaTracker tracker = null;
public void init() {
tracker = new MediaTracker(this);
for(int i = 0; i < fileNames.length; i++) {
System.out.println(" path :"+this.getCodeBase());
image[i] = getImage(this.getCodeBase(),fileNames[i]);
image[i] = image[i].getScaledInstance(256, 256, Image.SCALE_SMOOTH);
tracker.addImage(image[i], i);
}
try {
tracker.waitForAll();
}
}
Create your own customImageAdapter extending ArrayAdapter.
Sample code for your arrayAdapter:
public class CustomImageAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public CustomImageAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
// if you want to display the image modify the content according o your need
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image);//thumb image
return vi;
}