I have developed an app that is suppose to display images located in the drawable folder. I used imageview/viewpager for it. However, I would like to display frame shown below.On the top of the image so that image appears more fancy.. Also, the frame should swipe along with the image...so that it looks more beautiful... I was thinking of creating it permanently on the image...through photoshop... But I didn't like that idea ..So I thought may be android have something for it....I am android beginner...So any code help along with explanation will be appreciated..Following are my codes..
Mainactivity.java
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
public class MainActivity extends Activity {
MediaPlayer oursong;
ViewPager viewPager;
ImageAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
oursong = MediaPlayer.create(MainActivity.this, R.raw.a);
oursong.seekTo(0);
oursong.start();
viewPager = (ViewPager) findViewById(R.id.view_pager);
adapter = new ImageAdapter(this);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(MyViewPagerListener);
}
private int pos = 0;
#Override
protected void onPause() {
super.onPause();
if(oursong != null){
pos = oursong.getCurrentPosition();
oursong.release();
oursong = null;
}
}
#Override
protected void onResume(){
super.onResume();
oursong = MediaPlayer.create(MainActivity.this, R.raw.a);
oursong.seekTo(pos); // You will probably want to save an int to restore here
oursong.start();
}
private final OnPageChangeListener MyViewPagerListener = new OnPageChangeListener() {
#Override
public void onPageSelected(int pos) {
if (pos == adapter.getCount() - 1){
// adding null checks for safety
if(oursong != null){
oursong.pause();
}
} else if (!oursong.isPlaying()){
// adding null check for safety
if(oursong != null){
oursong.start();
}
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
};
}
Imageadapter.java
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class ImageAdapter extends PagerAdapter {
Context context;
private int[] GalImages = new int[] {
R.drawable.one,
R.drawable.two,
R.drawable.three,
R.drawable.four,
R.drawable.five
};
ImageAdapter(Context context){
this.context=context;
}
#Override
public int getCount() {
return GalImages.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.padding_small);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(GalImages[position]);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:icon="#drawable/icon" >
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="#drawable/icon" />
<ImageView
android:id="#+id/swipe_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="#drawable/swipe_left" />
<ImageView
android:id="#+id/swipe_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/swipe_right" />
</RelativeLayout>
Edited
Hidden portion of the image under frame
You can do it using a LayerDrawable
A Drawable that manages an array of other Drawables. These are drawn
in array order, so the element with the largest index will be drawn on
top.
You have two choices to use LayerDrawable.You can either define it in a separate drawable xml and then simply set the image in your ImageView, or you can configure a LayerDrawable dynamically in your code.
Programmatically using code
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = r.getDrawable(R.drawable.yourImage);;
layers[1] = r.getDrawable(R.drawable.yourFrame);
LayerDrawable layerDrawable = new LayerDrawable(layers);
imageView.setImageDrawable(layerDrawable);
Now you have your ImageView having two images(1.your image and 2.Frame) set on it.
Edit :
In your ImageAdapter, you need to modify instantiateItem(ViewGroup container, int position) something like
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.padding_small);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
Resources r = context.getResources();
Drawable[] layers = new Drawable[2];
layers[0] = r.getDrawable(GalImages[position]);
layers[1] = r.getDrawable(R.drawable.yourFrame);
LayerDrawable layerDrawable = new LayerDrawable(layers);
imageView.setImageDrawable(layerDrawable);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
Edit 2
As some portions of your image gets hidden under the frame, you need to set the width and height of your image before using it in the ImageView.Have some calculations of what could be the best width and height combination for your image, such that it will fit exactly with your frame.For setting height and width of your image
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.padding_small);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
Resources r = context.getResources();
Bitmap bmp = BitmapFactory.decodeResource(r, GalImages[position]);
int width=200;//set your width
int height=200;//set your height
Bitmap resizedbitmap = Bitmap.createScaledBitmap(bmp, width, height, true);
Drawable d = new BitmapDrawable(r,resizedbitmap);
Drawable[] layers = new Drawable[2];
layers[0] = d;
layers[1] = r.getDrawable(R.drawable.yourFrame);
LayerDrawable layerDrawable = new LayerDrawable(layers);
imageView.setImageDrawable(layerDrawable);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
Using XML
Create a new Drawable XML file, let's call it mylayer.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/yourimage" />
<item android:drawable="#drawable/yourframe" />
</layer-list>
Now in your Activity set the image using that Drawable:
imageView.setImageDrawable(getResources().getDrawable(R.layout.mylayer));
I hope this gives you the basic idea for achieving what you want.
Related
I have implemented Gridview, but the images from the phone gallery is not appearing in the particular GridView.
The scroll seems to be big enough as the scrollbar appearing on the right side scrolls along to the bottom. Then why I couldn't see the images.
GalleryGridAdapter.java
package com.test.Adapter;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.ImageView;
import com.test.R;
public class GalleryGridAdapter extends CursorAdapter
{
private Context mContext;
private Cursor mCursor;
private int mColumnIndex;
private ImageView imageView;
#SuppressWarnings("deprecation")
public GalleryGridAdapter(Context context, Cursor c, int ci) {
super(context, c);
mContext = context;
mCursor = c;
mColumnIndex = ci;
}
#Override
public void bindView(View view, Context context, Cursor curs)
{
ImageView imageView = (ImageView) view;
int id = curs.getInt(mColumnIndex);
imageView.setImageURI( Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
String.valueOf(id)));
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
}
#Override
public View newView(Context context, Cursor curs, ViewGroup parent)
{
return new ImageView(context);
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public int mygetItemId(int position) {
return 0;
}
}
MyActivity.java
String[] projection = {MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.DATA};
final Cursor cursor = context.getContentResolver().query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, null, null,
MediaStore.Images.Thumbnails.IMAGE_ID);
int columnIndex = 0;
if (cursor != null) {
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
GridView gridview = (GridView) findViewById(R.id.gridViewGallery);
gridview.setAdapter(new GalleryGridAdapter(getApplicationContext(), cursor, columnIndex));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.e("selected Image",cursor.getColumnName(i)+"");
}
});
}
use xml code like :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/bg_child">
<FrameLayout android:id="#+id/FrameLayout01"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="#+id/LinearLayout01"
android:layout_gravity="top" android:layout_height="50dp" android:layout_width="fill_parent">
<TextView android:id="#+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:layout_gravity="center_vertical" android:layout_marginLeft="30dp" android:gravity="center_vertical" android:drawableLeft="#drawable/photo_frame" android:textColor="#color/grey" android:text="#string/photogallery_txt"></TextView>
<Button android:layout_gravity="right" android:id="#+id/btnMoreInfo" android:layout_marginRight="5dp" android:layout_marginTop="5dp" android:textStyle="bold" android:background="#drawable/my_child_button" android:layout_width="100dp" android:layout_height="40dp" android:text="#string/moreinfo_txt"></Button>
</FrameLayout>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:columnWidth="90dp"
android:numColumns="auto_fit" android:verticalSpacing="10dp"
android:horizontalSpacing="10dp" android:stretchMode="columnWidth"
android:gravity="center" android:layout_gravity="bottom"
android:layout_marginTop="50dp"/>
</FrameLayout>
use code like :
public class GalleryPage extends Activity {
private static Uri[] mUrls = null;
private static String[] strUrls = null;
private String[] mNames = null;
private GridView gridview = null;
private Cursor cc = null;
private Button btnMoreInfo = null;
private ProgressDialog myProgressDialog = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gallery);
btnMoreInfo = (Button) findViewById(R.id.btnMoreInfo);
// It have to be matched with the directory in SDCard
cc = this.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,
null);
if (cc != null) {
myProgressDialog = new ProgressDialog(GalleryPage.this);
myProgressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
myProgressDialog.setMessage(getResources().getString(R.string.pls_wait_txt));
myProgressDialog.show();
new Thread() {
public void run() {
try {
cc.moveToFirst();
mUrls = new Uri[cc.getCount()];
strUrls = new String[cc.getCount()];
mNames = new String[cc.getCount()];
for (int i = 0; i < cc.getCount(); i++) {
cc.moveToPosition(i);
mUrls[i] = Uri.parse(cc.getString(1));
strUrls[i] = cc.getString(1);
mNames[i] = cc.getString(3);
//Log.e("mNames[i]",mNames[i]+":"+cc.getColumnCount()+ " : " +cc.getString(3));
}
} catch (Exception e) {
}
myProgressDialog.dismiss();
}
}.start();
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Intent i = new Intent(GalleryPage.this, BigImage.class);
Log.e("intent : ", ""+position);
i.putExtra("imgUrls", strUrls);
i.putExtra("position", position);
startActivity(i);
}
});
}
btnMoreInfo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(GalleryPage.this, ChildLogin.class);
startActivity(i);
}
});
}
/**
* This class loads the image gallery in grid view.
*
*/
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return cc.getCount();
}
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) {
View v = convertView;
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.galchild, null);
try {
ImageView imageView = (ImageView) v.findViewById(R.id.ImageView01);
//imageView.setScaleType(ImageView.ScaleType.FIT_XY);
// imageView.setPadding(8, 8, 8, 8);
Bitmap bmp = decodeURI(mUrls[position].getPath());
//BitmapFactory.decodeFile(mUrls[position].getPath());
imageView.setImageBitmap(bmp);
//bmp.
TextView txtName = (TextView) v.findViewById(R.id.TextView01);
txtName.setText(mNames[position]);
} catch (Exception e) {
}
return v;
}
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
FlurryAgent.onStartSession(this, "***");
}
/**
* This method is to scale down the image
*/
public Bitmap decodeURI(String filePath){
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// Only scale if we need to
// (16384 buffer for img processing)
Boolean scaleByHeight = Math.abs(options.outHeight - 100) >= Math.abs(options.outWidth - 100);
if(options.outHeight * options.outWidth * 2 >= 16384){
// Load, scaling to smallest power of 2 that'll get it <= desired dimensions
double sampleSize = scaleByHeight
? options.outHeight / 100
: options.outWidth / 100;
options.inSampleSize =
(int)Math.pow(2d, Math.floor(
Math.log(sampleSize)/Math.log(2d)));
}
// Do the actual decoding
options.inJustDecodeBounds = false;
options.inTempStorage = new byte[512];
Bitmap output = BitmapFactory.decodeFile(filePath, options);
return output;
}
}
i'm having an issue working with CardViews . I`ve created a CardView containing 1 TextView and 2 ImageViews , which gets displayed in an RecycleView . When i try to update the contents of one of the CardViews (created 5 cards for testing) the interface starts to lag when scrolling over the updated card, but goes back to normal when i pass the item. It only happens when ImageViews are present , when substituting the ImageViews for say, TextViews with some random text in them, it works normally.
Now, here's my code , after that i'll add some more information that could be causing it.
First , the Adapter class, which also contains the items class and List :
public class MovieDetailsAdapter extends RecyclerView.Adapter<MovieDetailsAdapter.MovieViewHolder> {
public List<MovieDetails> movieList;
private static final String TAG = "MyAdapter";
public MovieDetailsAdapter() {
movieList = new ArrayList< MovieDetails>();
}
public void setItemCount(int count ,String title, Bitmap poster,Bitmap fanart ) {
movieList.clear();
movieList.addAll(generateDummyData(count, title, poster , fanart));
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return movieList.size();
}
public void addItem(int position,String title, Bitmap poster, Bitmap fanart) {
if (position > movieList.size()) return;
movieList.add(position, generateDummyItem(title, poster, fanart));
// notifyDataSetChanged();
notifyItemInserted(position);
}
public void updateItem(int position, String title, Bitmap poster, Bitmap fanart) {
if (position > movieList.size()) return;
movieList.add(position, generateDummyItem(title, poster, fanart));
notifyItemChanged(position);
// notifyDataSetChanged();
}
#Override
public MovieViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.card_layout_movies, viewGroup, false);
Log.d(TAG, "create header view holder");
return new MovieViewHolder(itemView);
}
#Override
public void onBindViewHolder(MovieViewHolder movieViewHolder, int i) {
Log.d(TAG, "bind header view holder");
MovieDetails mdet = movieList.get(i);
movieViewHolder.vTitle.setText(mdet.Title);
movieViewHolder.vPoster.setImageBitmap(mdet.imageViewPoster);
movieViewHolder.vFanart.setImageBitmap(mdet.imageViewFanart);
Log.d(TAG, "position: " + i + " holder: " + movieViewHolder + " text: " + movieViewHolder.vTitle);
}
public static class MovieViewHolder extends RecyclerView.ViewHolder {
protected TextView vTitle;
protected ImageView vPoster;
protected ImageView vFanart;
public MovieViewHolder(View v)
{
super(v);
vTitle = (TextView) v.findViewById(R.id.title);
vPoster = (ImageView) v.findViewById(R.id.imageViewPoster);
vFanart = (ImageView) v.findViewById(R.id.imageViewFanart);
}
}
public static class MovieDetails {
protected String title;
protected Bitmap imageViewPoster;
protected Bitmap imageViewFanart;
public MovieDetails(String title, Bitmap imageViewPoster,Bitmap imageViewFanart )
{
this.title = title;
this.imageViewPoster = imageViewPoster;
this.imageViewFanart = imageViewFanart;
}
}
public static MovieDetails generateDummyItem(String title, Bitmap poster, Bitmap fanart) {
MovieDetails mov = new MovieDetails(title, poster, fanart);
return mov;
}
public static List< MovieDetailsAdapter.MovieDetails> generateDummyData(int count, String title , Bitmap imageViewPoster, Bitmap imageviewFanart) {
ArrayList<MovieDetailsAdapter.MovieDetails> items = new ArrayList<MovieDetailsAdapter.MovieDetails>();
for (int i=0; i < count; i++) {
items.add(new MovieDetailsAdapter.MovieDetails(title, imageViewPoster, imageviewFanart));
}
return items;
}
}
Now, here is my main class , the activity class
public class MoviesListActivity extends AppCompatActivity {
public MovieDetailsAdapter ca = new MovieDetailsAdapter();
public RecyclerView recList;
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movies_list);
RecyclerView recList = (RecyclerView) findViewById(R.id.cardList);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recList.setLayoutManager(llm);
button = (Button) findViewById(R.id.button);
MyOnClickListener Listener = new MyOnClickListener();
button.setOnClickListener(Listener);
recList.setItemAnimator(null);
Bitmap bittest1 = decodeSampledBitmapFromResource(getResources(), R.drawable.poster_example, 640, 955);
Bitmap bittest2 = decodeSampledBitmapFromResource(getResources(), R.drawable.fanart_example, 800, 450);
ca.setItemCount(5, "TestingTitle", bittest1, bittest2);
recList.setAdapter(ca);
}
public class MyOnClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
Bitmap bittest12 = decodeSampledBitmapFromResource(getResources(), R.drawable.poster2, 640, 955);
Bitmap bittest22 = decodeSampledBitmapFromResource(getResources(), R.drawable.fanart2, 800, 450);
Toast.makeText(getApplicationContext(), "msg msg", Toast.LENGTH_SHORT).show();
ca.updateItem(1, "test", bittest12, bittest22);
// ca.addItem(1,"test",bittest12,bittest22);
break;
default:
break;
}
}
}
//------methods used for resizing the images down to smaller ones before loading into memory---//
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
And finally, not that i probably matters, my CardView XML.
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="4dp"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#color/bkg_card"
android:text="Movie Title"
android:gravity="center_vertical"
android:textColor="#android:color/white"
android:textSize="14dp"/>
<ImageView
android:elevation="5dp"
android:scaleType="fitCenter"
android:layout_width="100dp"
android:layout_height="150dp"
android:id="#+id/imageViewPoster"
android:text="Poster"
android:gravity="center_vertical"
android:layout_below="#id/title"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"/>
<ImageView
android:id="#+id/imageViewFanart"
android:scaleType="fitCenter"
android:layout_alignBottom="#+id/imageViewPoster"
android:layout_toEndOf="#+id/imageViewPoster"
android:layout_width= "235dp"
android:layout_height="122dp"
android:layout_marginRight="5dp"/>
</RelativeLayout>
Now , somebody in another discussion showed me this as a possible cause : Why RecyclerView.notifyItemChanged() will create a new ViewHolder and use both the old ViewHolder and new one?
So i added the Log items inside the onBind and onCreate methods of the Adapter to see if that could be causing it, and indeed, it`s not just creatind one additional ViewHolders, but 3 of them, and each time i scroll over the newly updated card, it seems to be re-binding, the onBind method seems to be called each time.
Setting the animation to 'null' as per the solution in the thread doesn't seem to have any effect in my case, so maybe that`s not what is causing it.
Any ideas ?
Well, i solved it. It seems to happen only when i'm loading the images via the XML method, if i load them with a 3rd party library like Picasso, the lag seems to dissapear. Something like :
Picasso.with(context).load(MovieDetails.getPoster())
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(movieViewHolder.imageViewPoster);
inside the onBindViewHolder
and instead of passing around bitmaps, just pass a String for the URL or location of the image. And pass the Context to the Adapter class.
I am using view paper for image gallery, able to see all the images on swipe.
Here I want to set the image as wallpaper by clicking the "Set as wallpaper" button.
Below are the difficulties I am facing:
I am able to set the image as wallpaper successfully, but with constant image
Ex: R.drawable.picture3.But at run time when the images are loaded at each
turn different image will be displayed so cannot give this constant value
R.drawable.picture3.
How do I get the run time image id which is displayed?
Trying to achieve on click "Set as wallpaper" should set the current image
as wallpaper.
Note : v.getId()=R.drawable.picture1 not worked here both gave different value
Below is my code:
Context context;
Integer[] imageIDs = {
R.drawable.picture1,
R.drawable.picture2,
R.drawable.picture3,
R.drawable.picture4,
R.drawable.picture5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
ImageAdapter adapter = new ImageAdapter(this);
viewPager.setAdapter(adapter);
Button button=(Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setResource(R.drawable.picture3);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),
"Image is clicked-"+v.getBackground(), Toast.LENGTH_SHORT).show();
}
});
}
public class ImageAdapter extends PagerAdapter{
Context context;
int currentPosition;
private int[] GalImages = new int[] {
R.drawable.picture1,
R.drawable.picture2,
R.drawable.picture3,
R.drawable.picture4,
R.drawable.picture5,
};
ImageAdapter(Context context){
this.context=context;
}
#Override
public int getCount() {
return GalImages.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.abc_action_bar_content_inset_material);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageResource(GalImages[position]);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
</android.support.v4.view.ViewPager>
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="#cccccc"
android:text="#string/set_as_wallpaper" />
</RelativeLayout>
I don't want to achieve this in instantiateItem method in image adapter.
It's simple.If I got it correct then you want to set the image as wallpaper after clicking the button.Then here is the logic
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
curruntPosition=arg0; //Here you can the position
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
And then
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setResource(imageIDs[curruntPosition]);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),
"Image is clicked-"+v.getBackground(), Toast.LENGTH_SHORT).show();
}
});
Edit:
If you want to get the current viewable image from the viewpager
Maintain a list of images that are added dynamically say imageList then
int currentItem =viewPager.getCurrentItem();
Drawable drawable = getResource.getDrawable(imageList[currentItem]);
Bitmap bm =((BitmapDrawable) drawable).getBitmap();
I'm am fairly new to android development and ran into an issue where I am trying to create an image array that shows in a gallery and when I click on a picture, it shows the the pic at the bottom. When I run the app, it crashes. Any help i can get will be very very helpful. And thanks in advance.
My questions are
How do I get rid of the NullPointerException?
I'm I decoding the pictures correctly? Can someone show me a better way?
Thanks
My layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".PicturesActivity" >
<Gallery
android:id="#+id/gallery1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="16dp" />
<ImageView
android:id="#+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/trophykiss" />
</RelativeLayout>
MY CLASS:
public class PicturesActivity extends Activity {
Bitmap[] myImages = new Bitmap[] {
BitmapFactory.decodeResource(getResources(), R.drawable.champions),
BitmapFactory.decodeResource(getResources(), R.drawable.trophykiss),
BitmapFactory.decodeResource(getResources(), R.drawable.championstwo),
BitmapFactory.decodeResource(getResources(), R.drawable.trophies),
BitmapFactory.decodeResource(getResources(), R.drawable.culture),
BitmapFactory.decodeResource(getResources(), R.drawable.maintrophy),
BitmapFactory.decodeResource(getResources(), R.drawable.dive),
BitmapFactory.decodeResource(getResources(), R.drawable.naijamain),
BitmapFactory.decodeResource(getResources(), R.drawable.ethiopia),
BitmapFactory.decodeResource(getResources(), R.drawable.peru),
BitmapFactory.decodeResource(getResources(), R.drawable.funtime),
BitmapFactory.decodeResource(getResources(), R.drawable.skils),
BitmapFactory.decodeResource(getResources(), R.drawable.gabon),
BitmapFactory.decodeResource(getResources(), R.drawable.gambia),
BitmapFactory.decodeResource(getResources(), R.drawable.guinea)
};
private ImageView imageView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pictures);
Gallery g = (Gallery) findViewById(R.id.gallery1);
g.setAdapter(new ImageAdapter(this));
imageView = (ImageView) findViewById(R.id.image1);
g.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "pic: " + position,
Toast.LENGTH_SHORT).show();
imageView.setImageBitmap(myImages[position]);
}
});
}
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
TypedArray a = obtainStyledAttributes(R.styleable.MyGallery);
mGalleryItemBackground = a.getResourceId(
R.styleable.MyGallery_android_galleryItemBackground, 0);
a.recycle();
}
public int getCount() {
return myImages.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageBitmap(myImages[position]);
i.setLayoutParams(new Gallery.LayoutParams(200, 200));
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setBackgroundResource(mGalleryItemBackground);
return i;
}
}
}
ERROR MESSAGE:
java.lang.NullPointerException: Attempt to invoke virtual method
'android.content.res.Resources android.content.Context.getResources()
1)
You can't access your Context object before onCreate() has been called in your current activity. For the way you currently have it to work, just move the initialization of your array into your onCreate() method.
2)
Since you're decoding so many images at once, this should happen on a background thread. Look at the AsyncTask documentation for how to pull the image loading out into a separate thread.
I have an activity with some images and I'm using swipe to load the next image. I need when I touch the image to show a button, for image saving. How can I do that? Here's my code:
public class Photo_gallery extends Activity{
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_gallery);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
ImagePagerAdapter adapter = new ImagePagerAdapter();
viewPager.setAdapter(adapter);
}
private class ImagePagerAdapter extends PagerAdapter {
private int[] mImages = new int[] {
R.drawable.p1,
R.drawable.p2,
R.drawable.p3,
R.drawable.p4,
.
.
.
R.drawable.p108
};
public int getCount() {
return mImages.length;
}
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
public Object instantiateItem(ViewGroup container, int position) {
Context context = Photo_gallery.this;
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(
R.dimen.padding_medium);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setImageResource(mImages[position]);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
EDIT:
My XML code:
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
If you just want it to show a button on the screen when you click the image, you can put a button in your layout with the parameter android:visibility="gone".
Then, when the user clicks the image (just put an OnClickListener() for the ImageView), call button.setVisibility(View.VISIBLE); to show the button. Then when the user performs any other action and you want to hide the button again, call button.setVisibility(View.GONE);