I have an ArrayList which is bound to the listview, the custom row has a textview and an imageview, now when I click on any row I have given two functionality
1. Toast message to display position: which is displaying properly.
2. Open camera to capture an image and set that particular image to the row which was clicked.
Now the problem which I am facing is :
The image gets set but always to the last row and not to the row where it was clicked and when I click on the last row to capture image while setting the image it says IndexOutofBoundException
The code I have tried :
public class DocumentsKYCAdapter extends BaseAdapter{
private Context mContext;
private ArrayList<DocumentItem> gridName;
ArrayList<Integer> selectedDocumentId = new ArrayList<Integer>();
ArrayList<String> selectedDocumentNames = new ArrayList<String>();
ArrayList<Bitmap> selectedImages = new ArrayList<Bitmap>();
private Bitmap[] gridImage;
Documents_KYC activity;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final String IMAGE_DIRECTORY_NAME = "Imageview";
private Uri fileUri;
ImageView imageView;
public static byte[] b;
public static String encodedImageStr1;
int imageCapturedPosition;
public DocumentsKYCAdapter(Documents_KYC activity,
ArrayList<DocumentItem> gridName,ArrayList<Integer>
selectedDocumentId,ArrayList<String> selectedDocumentNames) {
this.activity = activity;
this.gridImage = gridImage;
this.gridName = gridName;
this.selectedDocumentNames = selectedDocumentNames;
this.selectedDocumentId = selectedDocumentId;
}
#Override
public int getCount() {
return selectedDocumentNames.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup
parent) {
View grid;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
grid = inflater.inflate(R.layout.documents_kyc_row, null);
} else {
grid = (View) convertView;
}
final String documentItemName =
selectedDocumentNames.get(position);
final int documentItemId = selectedDocumentId.get(position);
TextView textView = (TextView) grid.findViewById(R.id.gridName);
imageView = (ImageView) grid.findViewById(R.id.gridImage);
imageView.setTag(position);
textView.setText(documentItemName);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
imageCapturedPosition = position;
Toast.makeText(activity,"Id"+documentItemId+"
,Position"+imageCapturedPosition,Toast.LENGTH_LONG).
show();
imageView.getTag(position);
captureImage();
}
});
return grid;
}
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
activity.startActivityForResult(intent, MEDIA_TYPE_IMAGE);
}
public void onActivityResult(int requestCode, int resultCode, Intent
data) {
try {
if (requestCode == MEDIA_TYPE_IMAGE && resultCode ==
activity.RESULT_OK) {
BitmapFactory.Options options = new
BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap bitmap = Utility.decodeFile(fileUri.getPath(),
options);
FileOutputStream out = null;
try {
out = new FileOutputStream(fileUri.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
ByteArrayOutputStream baos = new
ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80,
baos);
b = baos.toByteArray();
encodedImageStr1 = Base64.encodeToString(b,
Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
selectedImages.add(bitmap);
imageView.setImageBitmap(selectedImages.
get(imageCapturedPosition));
} else if (resultCode == activity.RESULT_CANCELED) {
Toast.makeText(activity,
"User cancelled image capture",
Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(activity,
"Sorry! Failed to capture image",
Toast.LENGTH_SHORT)
.show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Custom Class :
public class BitmapModel {
Bitmap imageId;
ArrayList<String> documentNamesList;
public ArrayList<String> getDocumentNamesList() {
return documentNamesList;
}
public void setDocumentNamesList(ArrayList<String> documentNamesList) {
this.documentNamesList = documentNamesList;
}
public Bitmap getImageId() {
return imageId;
}
public void setImageId(Bitmap imageId) {
this.imageId = imageId;
}
}
Your issue is in the line -
selectedImages.add(bitmap);
Here whenever you add an image to your arrayList it always adds at the last position and then when you do imageView.setImageBitmap(selectedImages.get(imageCapturedPosition)); It tries to get the value for the position you selected which is not necessarily the last position.
The better way for you to do is create a Custom Class with Bitmap and selectedDocumentNames as part of the class then each object of the class would represent a name and an image associated with it.
Now when you capture the image, assign the image to the class Bitmap and then populate your listview with that Bitmap.
The workaround for your present code code be to either add the image into a particular position in array denoted by imageCapturedPosition or create a hashmap of type position,bitmap and then store it with the selected position. though i would not recommend any of these workarounds as they would cause other problems in future like memory leaks and positional movements in arrays etc and you would have to take care of these things
Related
I have a listview with a textview and imageview in each row, and am trying to figure out how to enlarge my images when clicking on them. The user takes an image from their gallery and stores them in a database with a name. They are maps of resorts/hotels for the purpose of delivering.
This is how everything is laid out:
I'm trying to get my app to where I can click on an ImageView, or simply just the listview itself, and have the image enlarged in the center of the screen. If not enlarged in the center of the screen, I wouldn't even mind opening the enlarged image in a new activity. Either way is fine, I would just like to be able to read the maps, so doing something with pinch-to-zoom would be great! I get the images from the user's gallery and store them in a list, and ask them for a name for the hotel/resort. Then I save the information to a database and display it in a listview. I crop the images down to fit them in the listview as thumbnails, but I would like to expand them back out upon being clicked for easy readability. Any help would be greatly appreciated! My goal is to have it look like the answer to this question, but couldn't figure out how to optimize it into my code.
My adapter class is as follows:
public class dataAdapter extends ArrayAdapter<Hotel> {
Context context;
ArrayList<Hotel> mHotel;
public dataAdapter(Context context, ArrayList<Hotel> hotel)
{
super(context, R.layout.listhotels, hotel);
this.context = context;
this.mHotel = hotel;
}
public class Holder
{
TextView nameFV;
ImageView pic;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Hotel data = getItem(position);
Holder viewHolder;
if (convertView == null)
{
viewHolder = new Holder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.listhotels, parent, false);
viewHolder.nameFV = (TextView) convertView.findViewById(R.id.txtViewer);
viewHolder.pic = (ImageView) convertView.findViewById(R.id.imgView);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (Holder) convertView.getTag();
}
viewHolder.nameFV.setText(data.getFName());
viewHolder.pic.setImageBitmap(convertToBitmap(data.getImage()));
return convertView;
}
private Bitmap convertToBitmap(byte[] b)
{
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
}
My code to display the list of hotels:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.display_hotels);
lv = (ListView) findViewById(R.id.list1);
db = new DatabaseHandler(this);
pic = (ImageView) findViewById(R.id.pic);
fname = (EditText) findViewById(R.id.txt1);
final ArrayList<Hotel> hotels = new ArrayList<>(db.getAllHotels());
data = new dataAdapter(this, hotels);
data.sort(new Comparator<Hotel>()
{
#Override
public int compare(Hotel arg0, Hotel arg1)
{
return arg0.getFName().compareTo(arg1.getFName());
}
});
data.notifyDataSetChanged();
lv.setAdapter(data);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
Intent i = new Intent(getApplicationContext(), display_full_image.class);
startActivity(i);
}
});
}
And my main activity:
public class MapsMainActivity extends AppCompatActivity {
private EditText fname;
private ImageView pic;
private DatabaseHandler db;
private String f_name;
private ListView lv;
private dataAdapter data;
private Hotel dataModel;
private Bitmap bp;
private byte[] photo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_main);
db = new DatabaseHandler(this);
lv = (ListView) findViewById(R.id.list1);
pic = (ImageView) findViewById(R.id.pic);
fname = (EditText) findViewById(R.id.txt1);
}
public void buttonClicked(View v)
{
int id = v.getId();
switch(id)
{
case R.id.save:
if (fname.getText().toString().trim().equals(""))
{
Toast.makeText(getApplicationContext(), "Name edit text is empty, Enter name", Toast.LENGTH_LONG).show();
}
else
{
addHotel();
}
break;
case R.id.display:
showRecords();
Intent intent = new Intent(getApplicationContext(), display_hotels.class);
startActivity(intent);
break;
case R.id.pic:
selectImage();
break;
}
}
public void selectImage()
{
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 2);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch(requestCode)
{
case 2:
if(resultCode == RESULT_OK)
{
Uri chosenImage = data.getData();
if(chosenImage != null)
{
bp = decodeUri(chosenImage, 400);
pic.setImageBitmap(bp);
}
}
}
}
protected Bitmap decodeUri(Uri selectedImage, int REQUIRED_SIZE)
{
try
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
{
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private byte[] profileImage(Bitmap b)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 0, bos);
return bos.toByteArray();
}
private void getValues()
{
f_name = fname.getText().toString();
photo = profileImage(bp);
}
private void addHotel()
{
getValues();
db.addHotels(new Hotel(f_name, photo));
Toast.makeText(getApplicationContext(), "Saved successfully", Toast.LENGTH_SHORT).show();
}
private void showRecords()
{
final ArrayList<Hotel> hotels = new ArrayList<>(db.getAllHotels());
data = new dataAdapter(this, hotels);
data.notifyDataSetChanged();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
dataModel = hotels.get(position);
Toast.makeText(getApplicationContext(), String.valueOf(dataModel.getID()), Toast.LENGTH_SHORT).show();
}
});
}
}
Thank you in advance to anyone who can help me. I would greatly appreciate it. This is for a final project for my Mobile App Development class that is due in 2 days, and I'm really close to finishing it. Thank you for your time.
use this getView()
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Hotel data = getItem(position);
Holder viewHolder;
if (convertView == null)
{
viewHolder = new Holder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.listhotels, parent, false);
viewHolder.nameFV = (TextView) convertView.findViewById(R.id.txtViewer);
viewHolder.pic = (ImageView) convertView.findViewById(R.id.imgView);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (Holder) convertView.getTag();
}
viewHolder.nameFV.setText(data.getFName());
viewHolder.pic.setImageBitmap(convertToBitmap(data.getImage()));
viewHolder.pic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Dialog settingsDialog = new Dialog(context);
settingsDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(500, 500);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
ImageView iv = new ImageView(context);
iv.setLayoutParams(lp);
iv.setImageResource(R.drawable.img3);
//use in your case iv.setImageBitmap(convertToBitmap(data.getImage()));
settingsDialog.addContentView(iv,lp);
settingsDialog.show();
}
});
return convertView;
}
just pass the imgeData as extra in intent when you start new Activity to display full image. and in FullImageActivit getIntent extra to get the image data and display it in an imageView.
and if you want to enable pinch zoom there a librabry to handle it
check this
In my CheckOutMemo.class I can set any title and content as shown in picture.
MainActivity.class then retrieves this title and content without any problems and displays a custom row. Like in this picture:
Title = Header
Content = bodyText
But the problem is: When I take a picture - I can't display it on my custom row. (That little dog in my MainActivity is there by default).
I don't know what the problem is.
I can preview my captured image as an Bitmap in my CheckOutMemo.class's contentView. I can successfully save it to my External Storage. But I can't display it on my MainActivity.
MAINACTIVITY.CLASS
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemLongClickListener, AdapterView.OnItemClickListener {
public ImageView view;
private String[] mPermission = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
private static final int REQUEST_CODE_PERMISSION = 5;
CustomAdapter customAdapter;
ListView listView;
Intent intent;
final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customAdapter = new CustomAdapter();
listView = (ListView) findViewById(R.id.myListView);
listView.setAdapter(customAdapter);
listView.setOnItemLongClickListener(this);
listView.setOnItemClickListener(this);
view = (ImageView) this.findViewById(R.id.imageIcon);
if (ActivityCompat.checkSelfPermission(MainActivity.this, mPermission[0])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(MainActivity.this, mPermission[1])
!= MockPackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
mPermission, REQUEST_CODE_PERMISSION);
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Memo memo = customAdapter.getItem(position);
intent = new Intent(getApplicationContext(), CheckOutMemo.class);
intent.putExtra("header", memo.header);
intent.putExtra("bodyText", memo.bodyText);
intent.putExtra("position", position);
// launches edit request and saving existing item.
startActivityForResult(intent, CheckOutMemo.EDIT_REQUEST_CODE);
}
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Confirm Delete");
alertDialogBuilder.setMessage("Delete memo?");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
customAdapter.delete(position);
customAdapter.notifyDataSetChanged();
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
return true;
}
public void addNewNote(View view) {
Intent intent = new Intent(getApplicationContext(), CheckOutMemo.class);
//Adding new listItem to the ArrayList.
startActivityForResult(intent, CheckOutMemo.ADD_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == CheckOutMemo.ADD_REQUEST_CODE) {
String header = data.getStringExtra("header");
String bodyText = data.getStringExtra("bodyText");
if (getIntent().hasExtra("byteArray")) {
Bitmap bitmap = BitmapFactory.decodeByteArray(
getIntent().getByteArrayExtra("byteArray"), 0, getIntent().getByteArrayExtra("byteArray").length);
view.setImageBitmap(bitmap);
}
Memo memo = new Memo(header, bodyText, view);
customAdapter.add(memo);
customAdapter.notifyDataSetChanged();
}
if (requestCode == CheckOutMemo.EDIT_REQUEST_CODE) {
int position = data.getIntExtra("position", 0);
Memo memo = customAdapter.getItem(position);
memo.header = data.getStringExtra("header");
memo.bodyText = data.getStringExtra("bodyText");
customAdapter.notifyDataSetChanged();
}
}
}
CHECKOUTMEMO.CLASS
public class CheckOutMemo extends AppCompatActivity {
public static final int ADD_REQUEST_CODE = 1;
public static final int EDIT_REQUEST_CODE = 2;
public static final int REQUEST_IMAGE_CAPTURE = 1337;
public String fileName;
public Bitmap bitmap;
private int position;
EditText editableTitle;
EditText editableContent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent intent = getIntent();
editableTitle = (EditText) findViewById(R.id.editHeader);
editableContent = (EditText) findViewById(R.id.editBodyText);
editableTitle.setText(intent.getStringExtra("header"));
editableContent.setText(intent.getStringExtra("bodyText"));
checkIfUserChangedOrWroteAnyText();
//Declaring keyword and default position.
position = intent.getIntExtra("position", 0);
}
public void capturePhoto(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
loadImageFromFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void loadImageFromFile() throws IOException {
ImageView view = (ImageView)this.findViewById(R.id.primeImage);
view.setVisibility(View.VISIBLE);
int targetW = view.getWidth();
int targetH = view.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bitmap = BitmapFactory.decodeFile(fileName, bmOptions);
view.setImageBitmap(bitmap);
}
public void createImageFromBitmap(){
if(bitmap!=null) {
Intent i = new Intent(this, MainActivity.class);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, bs);
i.putExtra("byteArray", bs.toByteArray());
startActivity(i);
} else {
Toast.makeText(CheckOutMemo.this, "Bitmap is null", Toast.LENGTH_SHORT).show();
}
}
public void onSaveClick(View view){
String editableContentString = editableContent.getText().toString();
String editableTitleString = editableTitle.getText().toString();
if(TextUtils.isEmpty(editableContentString) && TextUtils.isEmpty(editableTitleString)) {
finish();
Toast.makeText(CheckOutMemo.this, "No content to save, note discarded", Toast.LENGTH_SHORT).show();
}
else {
if ((TextUtils.isEmpty(editableTitleString))) {
editableTitleString.equals(editableContentString);
Intent intent = new Intent();
createImageFromBitmap();
intent.putExtra("header", editableContent.getText().toString());
intent.putExtra("position", position);
//Sending userInput back to MainActivity.
setResult(Activity.RESULT_OK, intent);
finish();
} else {
Intent intent = new Intent();
createImageFromBitmap();
intent.putExtra("header", editableTitle.getText().toString());
intent.putExtra("bodyText", editableContent.getText().toString());
intent.putExtra("position", position);
//Sending userInput back to MainActivity.
setResult(Activity.RESULT_OK, intent);
finish();
}
}
}
public void cancelButtonClickedAfterEdit() {
Button button = (Button) findViewById(R.id.bigCancelButton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
openDialogFragment(v);
}
});
}
public File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
String folder_main = "DNote";
String path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).toString() + File.separator + folder_main;
File storageDir = new File(path);
if (!storageDir.exists()) {
storageDir.mkdir();
}
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
fileName = image.getAbsolutePath();
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{image.getPath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// Log.i(TAG, "Scanned " + path);
}
});
return image;
}
#Override
public void onBackPressed() {
openDialogFragment(null);
}
public void onCancelClick(View view){
finish();
}
}
CUSTOMADAPTER.CLASS
public class CustomAdapter extends BaseAdapter {
ArrayList<Memo> memos = new ArrayList<>();
public void add(Memo memo) {
this.memos.add(memo);
}
public void delete(int position) {
memos.remove(position);
}
#Override
public Memo getItem(int position) {
return memos.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getCount() {
return memos.size();
}
class MyViewHolder {
public TextView header, bodyText;
public ImageView imageView;
public MyViewHolder(View view) {
header = (TextView) view.findViewById(R.id.header);
bodyText = (TextView) view.findViewById(R.id.bodyText);
imageView = (ImageView) view.findViewById(R.id.primeImage);
}
}
#Override
public View getView(final int position, View convertView, ViewGroup parent){
MyViewHolder viewHolder;
if(null == convertView){
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.custom_row, parent, false);
viewHolder = new MyViewHolder(convertView);
viewHolder.header.setTag(position);
convertView.setTag(viewHolder);
}
else{
viewHolder = (MyViewHolder) convertView.getTag();
}
Memo memo = getItem(position);
viewHolder.header.setText(memo.header);
viewHolder.bodyText.setText(memo.bodyText);
CheckOutMemo checkOutMemo = new CheckOutMemo();;
if(checkOutMemo.bitmap!=null) {
viewHolder.imageView.setImageBitmap(checkOutMemo.bitmap);
}
return convertView;
}
}
MEMO.CLASS
public class Memo {
public String header, bodyText;
public ImageView imageView;
public Memo(String header, String bodyText, ImageView imageView){
this.header = header;
this.bodyText = bodyText;
this.imageView = imageView;
}
}
I've been working on this for over 2 months every day. Any help would be appreciated!!
Ok here is the minimal viable solution to get what you want. I just fixed it enough so an image is returned to your main activity. The rest of your issues are for you to fix. The only class I haven't touched is your Memo class. But that being said I highly recommend you update it to store a String with the path to the image instead of an ImageView.
But if for you what you want to do here are your files edited to work:
First custom adapter:
I've changed the lines where you get the image from memo, to check it's image view for a bitmap drawable and transfer that bitmap to the row's image view. There was no need to instantiate that CheckoutMemo activity here.
public class CustomAdapter extends BaseAdapter {
ArrayList<Memo> memos = new ArrayList<>();
public void add(Memo memo) {
this.memos.add(memo);
}
public void delete(int position) {
memos.remove(position);
}
#Override
public Memo getItem(int position) {
return memos.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getCount() {
return memos.size();
}
class MyViewHolder {
public TextView header, bodyText;
public ImageView imageView;
public MyViewHolder(View view) {
header = (TextView) view.findViewById(R.id.header);
bodyText = (TextView) view.findViewById(R.id.bodyText);
imageView = (ImageView) view.findViewById(R.id.primeImage);
}
}
#Override
public View getView(final int position, View convertView, ViewGroup parent){
MyViewHolder viewHolder;
if(null == convertView){
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.custom_row, parent, false);
viewHolder = new MyViewHolder(convertView);
viewHolder.header.setTag(position);
convertView.setTag(viewHolder);
}
else{
viewHolder = (MyViewHolder) convertView.getTag();
}
Memo memo = getItem(position);
viewHolder.header.setText(memo.header);
viewHolder.bodyText.setText(memo.bodyText);
if (memo.imageView.getDrawable() instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) memo.imageView.getDrawable();
viewHolder.imageView.setImageBitmap(bitmapDrawable.getBitmap());
}
return convertView;
}
}
Next your CheckoutMemo:
I've changed how your setResult methods work. I've also deleted the method createImageFromBitmap. It was problematic, and also caused confusion. That one was a doozy. The createImageFromBitmap method was creating another MainActivity... confused me for a bit why onActivityResult wasn't being called. It wasn't being called because you were creating another activity =/
Anyways in your intent you create with your results, you'll notice I am also adding the file path string to the image created. So that main activity can use it to get the image!
public class CheckOutMemo extends AppCompatActivity {
public static final int ADD_REQUEST_CODE = 1;
public static final int EDIT_REQUEST_CODE = 2;
public static final int REQUEST_IMAGE_CAPTURE = 1337;
public String fileName;
public Bitmap bitmap;
private int position;
EditText editableTitle;
EditText editableContent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent intent = getIntent();
editableTitle = (EditText) findViewById(R.id.editHeader);
editableContent = (EditText) findViewById(R.id.editBodyText);
editableTitle.setText(intent.getStringExtra("header"));
editableContent.setText(intent.getStringExtra("bodyText"));
//checkIfUserChangedOrWroteAnyText();
//Declaring keyword and default position.
position = intent.getIntExtra("position", 0);
}
public void capturePhoto(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
loadImageFromFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void loadImageFromFile() throws IOException {
ImageView view = (ImageView)this.findViewById(R.id.primeImage);
view.setVisibility(View.VISIBLE);
int targetW = view.getWidth();
int targetH = view.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bitmap = BitmapFactory.decodeFile(fileName, bmOptions);
view.setImageBitmap(bitmap);
}
public void onSaveClick(View view){
String editableContentString = editableContent.getText().toString();
String editableTitleString = editableTitle.getText().toString();
if(TextUtils.isEmpty(editableContentString) && TextUtils.isEmpty(editableTitleString)) {
finish();
Toast.makeText(CheckOutMemo.this, "No content to save, note discarded", Toast.LENGTH_SHORT).show();
}
else {
if ((TextUtils.isEmpty(editableTitleString))) {
editableTitleString.equals(editableContentString);
Intent intent = new Intent();
//createImageFromBitmap();
intent.putExtra("header", editableContent.getText().toString());
intent.putExtra("position", position);
intent.putExtra("photo", fileName);
//Sending userInput back to MainActivity.
setResult(AppCompatActivity.RESULT_OK, intent);
finish();
} else {
Intent intent = new Intent();
//createImageFromBitmap();
intent.putExtra("header", editableTitle.getText().toString());
intent.putExtra("bodyText", editableContent.getText().toString());
intent.putExtra("photo", fileName);
intent.putExtra("position", position);
//Sending userInput back to MainActivity.
setResult(AppCompatActivity.RESULT_OK, intent);
finish();
}
}
}
public void cancelButtonClickedAfterEdit() {
Button button = (Button) findViewById(R.id.bigCancelButton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
//openDialogFragment(v);
}
});
}
public File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
String folder_main = "DNote";
String path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).toString() + File.separator + folder_main;
File storageDir = new File(path);
if (!storageDir.exists()) {
storageDir.mkdir();
}
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
fileName = image.getAbsolutePath();
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{image.getPath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// Log.i(TAG, "Scanned " + path);
}
});
return image;
}
#Override
public void onBackPressed() {
//openDialogFragment(null);
}
public void onCancelClick(View view){
finish();
}
}
Finally your MainActivity:
In on activity result if the photo path exists. Then I am adding it to the memo object's image view to later be retrieved by the adapters ImageView. This can be upgraded a bit hence my comments above to be a little less convoluted by just passing the file path ;)
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemLongClickListener,
AdapterView.OnItemClickListener {
public ImageView view;
private String[] mPermission = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
private static final int REQUEST_CODE_PERMISSION = 5;
CustomAdapter customAdapter;
ListView listView;
Intent intent;
final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customAdapter = new CustomAdapter();
listView = (ListView) findViewById(R.id.myListView);
listView.setAdapter(customAdapter);
listView.setOnItemLongClickListener(this);
listView.setOnItemClickListener(this);
//view = (ImageView) this.findViewById(R.id.imageIcon);
if (ActivityCompat.checkSelfPermission(MainActivity.this, mPermission[0])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(MainActivity.this, mPermission[1])
!= MockPackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
mPermission, REQUEST_CODE_PERMISSION);
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Memo memo = customAdapter.getItem(position);
intent = new Intent(getApplicationContext(), CheckOutMemo.class);
intent.putExtra("header", memo.header);
intent.putExtra("bodyText", memo.bodyText);
intent.putExtra("position", position);
// launches edit request and saving existing item.
startActivityForResult(intent, CheckOutMemo.EDIT_REQUEST_CODE);
}
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Confirm Delete");
alertDialogBuilder.setMessage("Delete memo?");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
customAdapter.delete(position);
customAdapter.notifyDataSetChanged();
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
return true;
}
public void addNewNote(View view) {
Intent intent = new Intent(getApplicationContext(), CheckOutMemo.class);
//Adding new listItem to the ArrayList.
startActivityForResult(intent, CheckOutMemo.ADD_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == CheckOutMemo.ADD_REQUEST_CODE) {
String header = data.getStringExtra("header");
String bodyText = data.getStringExtra("bodyText");
File photo = new File(data.getStringExtra("photo"));
ImageView view = new ImageView(this);
if (photo.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(photo.getAbsolutePath());
view.setImageBitmap(myBitmap);
}
Memo memo = new Memo(header, bodyText, view);
customAdapter.add(memo);
customAdapter.notifyDataSetChanged();
}
if (requestCode == CheckOutMemo.EDIT_REQUEST_CODE) {
int position = data.getIntExtra("position", 0);
Memo memo = customAdapter.getItem(position);
memo.header = data.getStringExtra("header");
memo.bodyText = data.getStringExtra("bodyText");
File photo = new File(data.getStringExtra("photo"));
if (photo.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(photo.getAbsolutePath());
memo.imageView.setImageBitmap(myBitmap);
}
customAdapter.notifyDataSetChanged();
}
}
}
All in all, running this I can now see images in the notes created!
Keep at your project here. Two months is a good commitment. You are doing great, keep up the good work. There are more things you can improve in there! Just keep massaging it, and never give up.
You rock =)
I can get you the working project I've created to test this if needed.
I'm currently building an android app to apply filter on a bmp. I'm using the gpuimage lib. How it's done is that the bmp is show in a ListView which contain 8 filters. When scrolling down/up, we request the filtering of the bmp (b&w, sepia...). As the rendering take times, I display in my listview the original bmp and it's replace by the filtered image once done
Here is how the activity do it.
private ListView mFiltersView;
private void FiltersPreview(final Bitmap mBmp) {
boolean mPreview = true;
mPreviewBitmap = resizeBitmap(mBmp);
mCameraImageFiltersAdapter = new CameraImageFiltersAdapter(this, mPreviewBitmap, mPreview);
mFiltersView.setAdapter(mCameraImageFiltersAdapter);
mFiltersView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
mCameraImageFiltersAdapter.cancel();
mFiltersView.cancelPendingInputEvents();
mFiltersView.setAdapter(null);
final CameraFiltersFactory effect = (CameraFiltersFactory) v.findViewById(R.id.filteredImage).getTag();
BufferAnimationDrawable Loading = new BufferAnimationDrawable(getBaseContext());
Loading.setPrimaryColor(0xfffb633e);
LoadingScreen.setImageDrawable(Loading);
LoadingScreen.setVisibility(View.VISIBLE);
mFiltersView.setVisibility(View.GONE);
getActionBar().hide();
if(mBmp == null) Log.d(TAG,"mBitmap is null");
effect.save(mBmp, position, new GPUImage.OnPictureSavedListener() {
#Override
public void onPictureSaved(Uri uri) {
final Intent previewIntent = new Intent(FiltersSelectionActivity.this, PicturePreviewActivity.class);
previewIntent.setData(uri);
previewIntent.setAction(mActionTypes.toString());
previewIntent.putExtra("Type", "Filtered");
startActivityForResult(previewIntent, 0);
}
});
}
});
}
The mCameraImageFiltersAdapter is defined as :
public CameraImageFiltersAdapter(/*Activity activity, */Context c, Bitmap current, boolean isPreview) {
mContext = c;
mPreview = isPreview;
mCurrentBitmap = current;
mFilterIds = CAMERA_IMAGE_FILTERS == null
|| CAMERA_IMAGE_FILTERS.length == 0 ?
mFilterIds : CAMERA_IMAGE_FILTERS;
mFakeBitmap = mCurrentBitmap;
mFakeBitmap.setDensity(0);
mExecutorService = Executors.newFixedThreadPool(5);
}
private final Handler handler = new Handler();// handler to display images
public int getCount() { return mFilterIds.length; }
public long getItemId(int position) { return 0; }
public Object getItem(int position) { return null; }
#Override public int getViewTypeCount() { return mFilterIds.length; }
#Override public int getItemViewType(int position) { return position; }
final int stub_id = R.drawable.filter_preview_stub;
public ImageView filteredImage = null;
public TextView filteredText = null;
#SuppressLint("InflateParams")
public View getView(int position, View convertView, ViewGroup parent) {
mPosition = position;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_filter, null);
filteredImage = (ImageView) convertView.findViewById(R.id.filteredImage);
filteredImage.setImageBitmap(mFakeBitmap);
filteredText = (TextView) convertView.findViewById(R.id.textview);
queueFiltered(filteredImage, mPosition, filteredText);
}
return convertView;
}
private void queueFiltered(final ImageView view, final int position, final TextView text) {
final CameraFiltersFactory holder = new CameraFiltersFactory(mContext, view, text);
if(holder != null)
mExecutorService.submit(new FilterLoader(holder, position));
}
public void cancel() {
if(mExecutorService != null) mExecutorService.shutdownNow();
}
The CameraFilterFactoy is just a easy to use class to access to the GPUImage
public class CameraFiltersFactory {
private static final String TAG = CameraFiltersFactory.class.getSimpleName();
private final ImageView mImageView;
private final GPUImage mCameraImage;
private Bitmap mFilteredBitmap;
private int mCurrentEffect;
private Context mContext;
private Activity mActivity = null;
private TextView mFiltersText;
public CameraFiltersFactory(Context c, ImageView filteredImage, TextView filteredText) {
mImageView = filteredImage;
mImageView.setTag(this);
mContext = c;
mCameraImage = new GPUImage(mContext);
if(filteredText != null) {
mFiltersText = filteredText;
mFiltersText.setVisibility(View.VISIBLE);
}
if(mImageView != null) mActivity = (Activity) mContext;
}
public void generateFilteredBitmap(Bitmap bmp, int filtertype, boolean isPreview) {
mCurrentEffect = filtertype;
switch (mCurrentEffect) {
case R.id.blackandwhite:
mCameraImage.setFilter(new GPUImagePlusGrayscaleFilter(isPreview));
break;
case R.id.cool:
mCameraImage.setFilter(new GPUImagePlusCoolFilter(isPreview));
break;
case R.id.cool2:
mCameraImage.setFilter(new GPUImagePlusCool2Filter(isPreview));
break;
case R.id.faded:
mCameraImage.setFilter(new GPUImagePlusFadedFilter(mContext, isPreview));
break;
case R.id.hipster:
mCameraImage.setFilter(new GPUImagePlusHipsterFilter(mContext, isPreview));
break;
case R.id.sepia:
mCameraImage.setFilter(new GPUImagePlusSepiaFilter(isPreview));
break;
case R.id.vivid:
mCameraImage.setFilter(new GPUImagePlusVividFilter(isPreview));
break;
case R.id.warm:
mCameraImage.setFilter(new GPUImagePlusWarmFilter(mContext, isPreview));
break;
default:
Log.d("NONE", "None FAIT CHIER");
break;
}
mCameraImage.deleteImage();
mCameraImage.setImage(bmp);
mFilteredBitmap = mCameraImage.getBitmapWithFilterApplied();
}
#SuppressLint("SimpleDateFormat")
public void save(Bitmap bitmap, int filter_id, GPUImage.OnPictureSavedListener ofsl) {
Log.d("NONE", "Save request with filter: "+filter_id);
generateFilteredBitmap(bitmap, filter_id, false);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = timeStamp + ".jpg";
mCameraImage.saveToPictures(mFilteredBitmap, CameraSettings.CAMERA_ROLL_FOLDER, fileName, true, ofsl);
}
}
This code is working fine in the List view.
Once I click on a picture from the ListView, I get his position, stop Executor from the adapter and ask to the FilterFactory for a rendering.
If In the listview I wait that all the preview list image are showing the filter rendering, and then I click, the filter is correctly applied on the original bmp.
In case, I'm scrolling quickly down and the GPU is in progress to render the preview iamge and then click, the original bmp is not filtered. I have check that in both case, when I click the list view give the right filter position and that the case. It seems that if a rendering is in progress, I'm not able to cancel and ask for a new one.
Any idea why ? Any idea if I can cancel the current GPU rendering and start a new one. ?
Thanks
Use gpuImage.deleteImage(); method in your adapter class after getting the bitmap from the gpu image.
Before setting your image to the GPUImage, create your image thumbnail. So it will load fast.
GPUImaage gpuImage=new GPUImage(context);
gpuImage.setImage(your image);
gpuImage.setFilter(choose your filter);
gpuImage.requestRender();
imageView.setImageBitmap(gpuImage.getBitmapWithFilterApplied());
gpuImage.deleteImage();
Since I was getting out of memory error when a picture taken with the phones camera was added into the imageView inside GridView, I tried to rescale it - as a bitmap (This worked just fine). I now want to add the images into an Array from which the items are going to load in the GridViews ImageView.
What I tried :
public class ImageGridAdapter extends BaseAdapter {
public Uri imageUri;
public String picture;
ArrayList<Bitmap> bitmapArrayList = new ArrayList<Bitmap>();
private Context mContext;
public ImageGridAdapter(Context c) {
this.mContext = c;
}
#Override
public int getCount() {
return bitmapArrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
try {
imageUri = PictureGroupActivity.selectedImage;
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = mContext.getContentResolver().query(imageUri, filePathColumn, null, null, null);
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picture = cursor.getString(columnIndex);
cursor.close();
} catch (Exception e) {}
bitmapArrayList.add(BitmapScaled(picture, 100, 100));
Toast.makeText(mContext.getApplicationContext(), "bitmapArrayList je: " + bitmapArrayList, Toast.LENGTH_SHORT).show();
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(5, 5, 5, 5);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageBitmap(bitmapArrayList.get(position));
return imageView;
}
private Bitmap BitmapScaled(String picturePath, int width, int height) {
BitmapFactory.Options sizeOptions = new BitmapFactory.Options();
sizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picturePath, sizeOptions);
sizeOptions.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(picturePath, sizeOptions);
}
}
Setting the adapter to GridView:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picture_group_activity_layout);
GridView gridView = (GridView) findViewById(R.id.picture_group_gridView);
gridView.setAdapter(new ImageGridAdapter(this));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(PictureGroupActivity.this, "You clicked " + position, Toast.LENGTH_SHORT).show();
}
});
}
Choosing the Image:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
String picturePath = loadPath();
if (id == R.id.addPictureFolder) {
if (picturePath != null) {
Toast.makeText(this, "Click the plus button to add pictures", Toast.LENGTH_LONG).show();
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
} else {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
} else if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
gridView = (GridView)findViewById(R.id.picture_group_gridView);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
selectedImage = data.getData();
Intent restart = getIntent();
finish();
startActivity(restart);
}
}
This does like nothing, no error, no Image is displayed, nothing.
What am I doing wrong? (If I'm not anywhere near the answer, how do you do it?)
Thank you in advance!
It seems you are not setting arraylist in adapter from activity. bitmapArrayList size is zero thats why gridview not showing anything. Please check the bitmapArrayList size.
I am trying to create gallery with photos from sdcard. I have a database table. One of the columns in the table has a path to a photo.
I am following this link as a guideline, but this sample code retrieves image ids from res/drawable directory. I am not sure how to modify it to make my code work.
http://saigeethamn.blogspot.com/2010/05/gallery-view-android-developer-tutorial.html
But as mentioned, I want to display photos with whatever images exist in the database table. The following code is ImageAdapter.
public class ImageAdapter extends BaseAdapter {
private Context ctx;
int imageBackground;
public ImageAdapter(Context c) {
ctx = c;
TypedArray ta = obtainStyledAttributes(R.styleable.milestone_style);
imageBackground = ta.getResourceId(R.styleable.milestone_style_android_galleryItemBackground, 1);
ta.recycle();
}
#Override
public int getCount() {
return imagePhotosLocations.length;
}
#Override
public Object getItem(int arg0) {
return arg0;
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View arg1, ViewGroup arg2) {
if (milestones != null && !milestones.isEmpty()) {
Milestone milestone = milestones.get(0);
String imageFileLocation = milestone.getFileLocation();
System.out.println("imageFileLocation="+imageFileLocation);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 26;
Bitmap b;
ImageView iv = new ImageView(ctx);
try {
if (imageFileLocation.startsWith("content://")) {
b = BitmapFactory.decodeStream(getContentResolver().openInputStream(Uri.parse(imageFileLocation)), null, options);
} else {
b = BitmapFactory.decodeFile(imageFileLocation, options);
}
iv.setImageBitmap(b);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setLayoutParams(new Gallery.LayoutParams(150, 120));
// milestoneImageView.setBackgroundResource(imageBackground);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return iv;
}
return null;
}
}
And this is one of the methods in activity.
private String[] imagePhotosLocations;
private void init() {
milestones = getMilestones();
imagePhotosLocations = new String[milestones.size()];
int index = 0;
for (Milestone milestone : milestones) {
imagePhotosLocations[index++] = milestone.getFileLocation();
}
}
private void initializeGallery() {
milestoneImageView = (ImageView) this.findViewById(R.id.imagePhoto);
Gallery milestoneGallery = (Gallery) this.findViewById(R.id.milestoneGallery);
if (milestoneGallery == null) {
throw new IllegalArgumentException("milestoneGallery can not be null.");
}
milestoneGallery.setAdapter(new ImageAdapter(this));
milestoneGallery.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int which, long arg3) {
String imageFileLocation = imagePhotosLocations[which];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 26;
Bitmap b;
try {
if (imageFileLocation.startsWith("content://")) {
b = BitmapFactory.decodeStream(getContentResolver().openInputStream(Uri.parse(imageFileLocation)), null, options);
} else {
b = BitmapFactory.decodeFile(imageFileLocation, options);
}
milestoneImageView.setImageBitmap(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
});
}
Here are the steps which I used,
First check if the SD card is mounted.
Query your database.Details on this can be found here:
SQLite tutorial.
The Query returns a cursor for the result set.
Use a custom Cursor Adapter (Refer: Custom Cursor Adapter)
Some times if the image is too large ,loading the image into bitmap may exceed VM budget. So refer this article Avoiding out of memory issue while loading image
So the cursor adapter returns an image view as its done in your code.
finally bind this custom adapter to your gallary.
hope this answers your question.