I just started into this Android development thing, by my own, basically reading various books and searching the internet and the forums for the information that i need, but it seems I got to a halt. I am trying to make an application by which the user will be prompted with a list of images in a gridview. Upon clicking an image, the application will sent the user to an activity which will display a, sometimes short, sometimes long, story that is read from a .txt file placed inside the assets folder. I can do it the easy way, ie. making an activity for each .txt that needs to be opened but i'm talking 50+ image files in gridview and 50+ .txt files in assets folder. So I want to do this from only 2 activities, main and +1, or as few as possible. below is the code i got so far.
MainActivity.java
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridview = (GridView) findViewById (R.id.gridv);
gridview.setAdapter(new ImageAdapter (this));
gridview.setOnItemClickListener (new AdapterView.OnItemClickListener() {
public void onItemClick (AdapterView<?> parent, View v, int position, long id) {
Intent i = new Intent (getApplicationContext(), ChronText.class);
i.putExtra("id", position);
startActivity (i);
}
});
}
}
ChronText.java
public class ChronText extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flowtext);
Intent i = getIntent();
int position = i.getExtras().getInt("id");
TextView chronview = (TextView) findViewById (R.id.chronview);
AssetManager assetManager = getAssets();
InputStream input;
try {
input = assetManager.open("");
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
String text = new String (buffer);
chronview.setText(text);
} catch (IOException e) {
e.printStackTrace();
}
}
}
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
private Context myContext;
public Integer[] myThumbsId = {
R.drawable.breathingspace,
R.drawable.particletracks,
R.drawable.welcomeparty,
R.drawable.thebookofemptiness2of2,
R.drawable.uplifted
};
public ImageAdapter (Context c) {
myContext = c;
}
public int getCount() {
return myThumbsId.length;
}
public Object getItem (int position) {
return myThumbsId [position];
}
public long getItemId (int position) {
return 0;
}
public View getView (int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView (myContext);
imageView.setLayoutParams(new GridView.LayoutParams(170,111));
imageView.setImageResource(myThumbsId[position]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(5, 5, 5, 5);
return imageView;
}
}
The application works, however, I have to manually enter the filename in ChronText.java
InputStream input;
try {
input = assetManager.open("");
so basically, i would need to manually write the filename for each image that is clicked. Is there a way this thing could be done automatically? And if yes, how? The way I am thinking is to make a list containing all the filenames, like the gridview has, that contains the files in the corresponding order of the gridview images, and when the user clicks the image, the activity is created for the file that has the same position in filename list as the image in the gridview list. If there is another, simpler way, please, do tell/explain. If my idea is good, please tell me how to put it 'on paper'. I worked on this app for some weeks now and i'm a bit burned out. Thanks in advance.
After another week or so of head smashing, I have fount the answer and completed the app. I can show the result if anyone wishes to
Related
When setting an ArrayList of Uris in the gridView, only one item is displayed. Why ?
Adapter:
public class ImageGridAdapter extends BaseAdapter {
private Context mContext;
public ImageGridAdapter(Context c) {
this.mContext = c;
}
#Override
public int getCount() {
try {
return PictureGroupActivity.ALofSelectedImgs.size();
} catch (NullPointerException e) {
return 0;
}
}
#Override
public Object getItem(int position) {
return PictureGroupActivity.ALofSelectedImgs.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
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;
}
try {
imageView.setImageURI(PictureGroupActivity.ALofSelectedImgs.get(position));
Toast.makeText(mContext.getApplicationContext(), "Idee: " + PictureGroupActivity.ALofSelectedImgs, Toast.LENGTH_SHORT).show();
}catch (NullPointerException e) {}
return imageView;
}
Setting the adapter:
#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();
}
});
}
From where I take the Image (After choosing from the phones gallery):
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
selectedImage = data.getData();
ALofSelectedImgs = new ArrayList<Uri>();
ALofSelectedImgs.add(selectedImage);
Intent restart = getIntent();
finish();
startActivity(restart);
}
}
How do I make it add multiple Images into the ArrayList and make them stay there and not overwrite each other ?
There are a few problems that I can see with your approach here.
The simplest solution (changing the least code). Would be to move ALofSelectedImgs = new ArrayList(); from onActivityResult(int, int, Intent) and put it in onCreate(Bundle).
This still won't persist the data between orientation changes or closing the app. You'll get a new empty ArrayList every time onCreate(Bundle) is called.
And I wouldn't recommend using static fields like that. For starters, you can't use ImageGridAdapter with any other Activity or Fragment. You need to pass the List to it, either in the constructor or a setter method. That way you can reuse it more easily.
private Context mContext;
private List<Uri> mUris;
public ImageGridAdapter(Context context, List<Uri> uris) {
super(context);
mContext = context;
mUris = uris;
}
For a better solution... there are many ways to do this. Here's what I'd do:
Create a class extending SQLiteOpenHelper in order to save the selected Uris in an SQLite table. I learned a lot from this tutorial. I probably would not worry with a ContentProvider for something this simple. If you're interested I could pm you a template I use for keeping many tables' columns and other constants in a contract class.
Create an adapter extending SimpleCursorAdapter to create Views from a Cursor containing a query from your SQLite table. This is explained in the above tutorial.
In PhotoGroupActivity, perform a query of your table and initialize the adapter with the Cursor returned in onCreate(Bundle).
In onActivityResult(int, int, Intent) you need to insert the Uri into the SQLite table, then perform another query and give the adapter the new Cursor.
EDIT:
To answer your second question. This didn't occur to me at first, but you'll want to use thumbnails to display in your GridView. Use Bitmap.createScaledBitmap(Bitmap, int, int, boolean) to create the thumbnail. Store the thumbnail in your app's private storage to avoid it going in your gallery, then add the Uri to the thumbnail to your ArrayList. You'll probably want to keep track of the Uri for the full-size image as well for when the user touches the thumbnail.
Try using HashMap with the thumbnail Uri as the key and the full-size Uri as the value.
// Create the HashMap like this:
HashMap<Uri, Uri> uriMap = new HashMap<>();
// You have the main Uri. Get the bitmap, create a thumbnail and store it.
// Add an entry to the HashMap like this:
uriMap.put(thumbnailUri, fullSizeUri);
// To get the list of thumbnail Uris for the adapter:
List<Uri> thumbnailList = new ArrayList<>(uriMap.keySet());
// When user presses an image in GridView, get the relevant full-size
// Uri like this:
fullSizeUri = uriMap.get(thumbnailUri);
EDIT AGAIN:
I looked again and realised I suggested a CursorAdapter and then gave info on how to get a HashMap of the data.
Instead, just add another column to the SQLite table and store both Uris there. When you obtain the Uri and thumbnail Uri, store them both in the table and query the table for the SimpleCursorAdapter.
I'm new to android domain..
I'm working with small app..
What i need is ??
I have videos urls and image urls in a array list,which retrive from database as json object and stored in separate array. I want this array list of images should show in listview with text.
How to implement this?? please help me..
I have went through google but still i didn't clear example.. Please any one help me..
Thanks a lot in advance...
public class act extends Activity {
/** Called when the activity is first created. */
static String uri1="http://i3.ytimg.com/vi/bQaWsVQSLdY/default.jpg";
static String uri2="http://i4.ytimg.com/vi/cJQCniWQdno/mqdefault.jpg";
static String uri3="http://i1.ytimg.com/vi/D8dA4pE5hEY/mqdefault.jpg";
public static String[] urls={uri1,uri2,uri3};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GridView grd=(GridView)findViewById(R.id.gridView1);
grd.setAdapter(new ImageAdapter(this));
grd.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent,View v,int pos,long id)
{
Toast.makeText(getBaseContext(),"pic"+(pos+1)+"select ",Toast.LENGTH_SHORT).show();
}
});
}
public class ImageAdapter extends BaseAdapter
{
private Context context;
private int itemBackground;
ImageAdapter(Context c)
{
context=c;
TypedArray a=obtainStyledAttributes(R.styleable.Gallery1);
itemBackground=a.getResourceId(R.styleable.Gallery1_android_galleryItemBackground,0);
a.recycle();
}
public int getCount()
{
return urls.length;
}
public Object getItem(int pos)
{
return pos;
}
public long getItemId(int pos)
{
return pos;
}
public View getView(int pos,View cv,ViewGroup vg)
{
ImageView imageview=new ImageView(context);
imageview.setImageResource(urls[pos]);
imageview.setScaleType(ImageView.ScaleType.FIT_XY);
imageview.setLayoutParams(new Gallery.LayoutParams(150,120));
imageview.setBackgroundResource(itemBackground);
return imageview;
}
}
}
I try like this..i can't able to get the image...
you can't set it directly as you are trying to do, you will first need to download the image,
store the bitmap, and only then apply the image to you ImageView.
check this question:
How to set image button resource from web url in Android?
this solution is good as well:
How to load an ImageView by URL in Android?
If the requirement is of showing the imageview and textview in list row then try the concept of universal loader.
Link:
https://github.com/nostra13/Android-Universal-Image-Loader
I am creating thumbnails from videos stored in my sd card ,displaying thumbnails and its names in grid view. On item selected event of the grid view pop ups a dialog and asking x, y, right, bottom positions then pasting it to the main activity . I got the video files, and tried to create thumbnail using media store also am retrieving thumbnail as bitmap, but the bitmap is null. In the grid view video names are shown and i am able to select the corresponding thumbnail and can give positions also am able set the thumbnail to the main activity. The problem is the bitmap is null and bitmap image not showing(text vie video name shown). What's the problem ? I can't figure it out? Plz help me? My code is given below. thanks in advance.
if (f.isFile()) {
if (fName.endsWith(".mpg")
|| fName.endsWith(".mov")
|| fName.endsWith(".wmv")
|| fName.endsWith(".rm")
|| fName.endsWith(".mp4")) {
tv.setText(fName);
path = f.getAbsolutePath();
System.out.println("Video file path=>"+path);
thumb = ThumbnailUtils.createVideoThumbnail(f.getAbsolutePath(),MediaStore.Video.Thumbnails.MICRO_KIND);
if(thumb==null)
{
/**Every time it printing null**/
System.out.println("Thumb is null");
}
iv.setImageBitmap(thumb);
From ThumbnailUtils.createVideoThumbnail documentation: May return null if the video is corrupt or the format is not supported.
By default, almost all supported formats are mp4 and 3gp. See here: http://developer.android.com/guide/appendix/media-formats.html for full list of default-supported media formats.
If you are creating thumbnail from sd card video this would create ThumbnailUtils.createVideoThumbnail otherwise use a cursor.
See this example.
Try this code. It is getting the thumbnail of videos from urls. instead of pass the path of sd card .it will help you . Dont forgot to add internet permission in manifest file.
public class VideoThumbnailActivity extends Activity {
public static final String Downloader = null;
static String uri1="http://daily3gp.com/vids/lucky_guy.3gp";
static String uri2="http://daily3gp.com/vids/reporter_hit_by_plane.3gp";
static String uri3="http://daily3gp.com/vids/motorcycle_wipesout_explodes.3gp";
static String uri4="http://commonsware.com/misc/test2.3gp";
public static String uri_array[]={uri1,uri2,uri3,uri4,uri1,uri2,uri3,uri4,uri1,uri2,uri3,uri4};
ImageView imageView;
String url;
Gallery ga1,ga2;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView)findViewById(R.id.imageView);
ga1 = (Gallery)findViewById(R.id.gallery1);
ga1.setAdapter(new ImageAdapter(getApplicationContext()));
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(uri_array[0], MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
//on click event on gallery
ga1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, final int position,long arg3) {
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(uri_array[position], MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
//on click event on imageview to play video
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(),PlayActivity.class);
intent.putExtra("path",uri_array[position]);
startActivity(intent);
}
});
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context ctx;
int imageBackground;
public ImageAdapter(Context c) {
ctx = c;
TypedArray ta = obtainStyledAttributes(R.styleable.Gallery1);
imageBackground = ta.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 1);
ta.recycle();
}
#Override
public int getCount() {
return uri_array.length;
}
#Override
public Object getItem(int arg0) {
return arg0;
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View view, ViewGroup arg2) {
ImageView iv = new ImageView(ctx);
Bitmap curThumb = null;
curThumb = ThumbnailUtils.createVideoThumbnail(uri_array[position],MediaStore.Video.Thumbnails.FULL_SCREEN_KIND);
iv.setImageBitmap(curThumb);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setLayoutParams(new Gallery.LayoutParams(150,120));
iv.setBackgroundResource(imageBackground);
return iv;
}
}
let me know your problem is resolved or not.
So I have a Gridview and and ImageAdapter class. The images all get grab from a folder and then populated into the grid view. I then have another class that displays the full image when clicked. However whenever someone clicks an image ImageAdapter has to get called again and all the images need to be repopulated into my variables and then I just pick out the one I need. This is terribly inefficient but I don't know how to do it otherwise.
Here is my code.
Main Classes (favorites in this case) with the grid view
public class Favorites extends Activity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.favorites);
GridView gridview = (GridView) findViewById(R.id.favgridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,View v, int position, long id){
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
i.putExtra("id", position);
startActivity(i);
}
});
}
}
My ImageAdapter class, you can see that I load all the images as bitmaps into an array.
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private Bitmap[]mis_fotos;
public ImageAdapter(Context c){
mContext = c;
}
public int getCount(){
get_images();
return mis_fotos.length;
}
public Bitmap getItem(int position){
get_images();
return mis_fotos[position];
}
public long getItemId(int position){
return 0;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView imageView;
if (convertView == null){
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.setImageBitmap(mis_fotos[position]);
return imageView;
}
private void get_images(){
String dirPath = mContext.getFilesDir().getAbsolutePath() + File.separator + "favorites";
File directory = new File(dirPath);
File[] archivos = directory.listFiles();
mis_fotos = new Bitmap[archivos.length];
for (int cont=0; cont<archivos.length;cont++){
File imgFile = new File(archivos[cont].toString());
mis_fotos[cont] = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
}
}
}
And Finally my Full Image Class
public class FullImageActivity extends Activity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.full_image);
Intent i = getIntent();
int position = i.getExtras().getInt("id");
ImageAdapter imageAdapter = new ImageAdapter(this);
ImageView imageView = (ImageView) findViewById(R.id.full_image_view);
imageView.setImageBitmap(imageAdapter.getItem(position));
}
}
So you can see that when I use the full image all I can pass is the position integer from the gridview class. I then have to call get_images() again in the ImageAdapter class and repopulate an array all over again.
All I need to to pass a single image from the gridview to the fullimage class when an image is clicked. I know there is an easier and far more efficient way to do this. I hope this makes sense.
Work around required, you are calling get_images() multiple times inside an Adapter class which is a bad way. Better solution is remove it from Adapter class and keep inside the MainActivity and just call it before setting the Adapter like,
GridView gridview = (GridView) findViewById(R.id.gridView);
get_images();
gridview.setAdapter(new ImageAdapter(this));
And then your method for Adapter class should be like,
public int getCount() {
return mis_fotos.length;
}
public Object getItem(int position) {
return mis_fotos[position];
}
Now, I come to your issue that is you want to show an Image as fullscreen to Next Activity. So, why don't you fetch the Bitmap from clicked ListView Item and pass it to Next Activity?. So, how can you do that? Here it is,
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Bitmap bitmap = (Bitmap) parent.getAdapter().getItem(position);
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
i.putExtras(bundle);
startActivity(i);
});
So, nothing tricky, just getting the Bitmap using getItem(position); and the sending it to Next Activity using Bundle. Now you can easily get the Bitmap using
Bundle bundle = getIntent().getExtras();
Bitmap bitmap = bundle.getParcelable("bitmap");
// create new Bitmap with any height, width required by you.
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
and show to ImageView.
I have an app with the GridView layout have a single image for testing purposes until I figure out this next step. I have everything set up, but I don't know how implement a design where image A, B, C, D, etc. are clicked result in the user (me) landing on a webpage that I specify. I need each image to link to different locations and I would really appreciate the help to implement this into my code:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create new ImageView for each item
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(5, 5, 5, 5);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to images
private Integer[] mThumbIds = {
R.drawable.A, R.drawable.B,
R.drawable.C, R.drawable.D,
R.drawable.E, R.drawable.F,
R.drawable.G, R.drawable.H,
};
}
Use the getItemId() in your adapter (just return the position) to select the URL you want to go to. Just like you have mThumbIds, just have a parallel array that holds the matching URLs, so when an image is clicked, its corresponding URL can be accessed easily at the same index.
The "zero-work" method of doing this would be to simply launch an Intent that would open the URL in the device's browser from an OnItemClickListener. Something like:
//Obtain a reference to the view in your layout somehow...I chose findViewById()
GridView grid = (GridView)findViewById(R.id.peters_grid);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//"position" is the location of the image clicked
String url = arrayOfUrls[position];
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
}
});
Where you are grabbing the correct URL for each position from an array of Strings. This is just one idea for getting the right URL...you could construct the proper URL a million different ways, but the key is to pass it to the Intent and then fire it.
The "little work" version of this would be to create a WebView in this or another Activity so you can load the web page and stay within your application code. If the WebView is in a second Activity, it would still be best to use an Intent to pass the URL string from the first Activity to the second.
Hope that Helps!