Android Viewpager to load images from SD Card - image

Guys Im using the following custom code to load 20 images from resources and present in a viewpager
public class CustomPagerAdapter extends PagerAdapter {
int[] mResources = {
R.drawable.slide1,
R.drawable.slide2,
R.drawable.slide3,
R.drawable.slide4,
R.drawable.slide5,
R.drawable.slide6,
R.drawable.slide7,
R.drawable.slide8,
R.drawable.slide9,
R.drawable.slide10,
R.drawable.slide11,
R.drawable.slide12,
R.drawable.slide13,
R.drawable.slide14,
R.drawable.slide15,
R.drawable.slide16,
R.drawable.slide17,
R.drawable.slide18,
R.drawable.slide19,
R.drawable.slide20,
};
Context mContext;
LayoutInflater mLayoutInflater;
public CustomPagerAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mResources.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.pager_item, container, false);
ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
imageView.setImageResource(mResources[position]);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
This works fine but I want to put the jpgs in a directory on the device so that they can be changed without recompiling the app
I think I need to get the images into the mResource array. I can get the path but not sure what format the code should be instead of using the draw-able lines
i have read articles on here but none make sense to me I am really new to this and the code looks nothing like the code I am using
can anyone point me in the right direction?
Any help is greatly appreciated
Mark

Yes, you can certainly do so. I will try to explain you the process step-by-step,
Step 1
Have a File object pointing to the path, like,
File directory = new File("path-to-directory");
Ensure that the path is to the directory with the images,
Step 2
List all the files inside the directory using listFiles() method, like
File[] allImages = directory.listFiles();
Now you have an array of all the files just like int[] mResources. The only difference being, now you have actual file references, while previously you had resource ids.
Step 3
You can just display the images in the ViewPager just like you did previously. But this is a bit tricky and can take you a considerable amount of time and code to get an image properly displayed from File.
You also need to take care of caching, so that when you load a previously loaded image again, it gets it from the cache.
To do all this, I recommend you to use this library (recommended by Google), Glide.
Setting an image is one line of code,
Glide.with(context).from(file).into(imageView);
That's it. Now you have your images displayed in a ViewPager from a directory in the device.

Related

JavaFX Export Scene as PDF/SVG

I have currently developed an ultimately open source application to analyse some data in a table view and visualise the resulting data in some additional plots. A problematic thing with this is, that the generated plots could potentially be useful for end users for e.g. a presentation, further downstream informative discussion and so on. This is why I started working on an export function using ImageWriter
//adding a context menu item to the chart
final MenuItem saveAsPng = new MenuItem("Save as png");
saveAsPng.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
int scale = 6; //6x resolution should be enough, users should downscale if required
final Bounds bounds = bc.getLayoutBounds();
final SnapshotParameters spa = new SnapshotParameters();
spa.setTransform(javafx.scene.transform.Transform.scale(scale, scale));
ImageWriter imageWriter = new ImageWriter();
try {
imageWriter.saveImage(stage, bc.snapshot(spa, null));
} catch (ImageException e) {
e.printStackTrace();
}
}
});
This successfully creates a PNG file with sufficient size, but my ideal solution would be to export in vector-based format, e.g. PDF/SVG. For Swing applications, I knew how to achieve this, but for JFX I couldn't really find a proper solution for that matter. I already investigated several potential ideas, e.g. using a printer dialogue and then exporting as a PDF via virtual printer, but that does result in a bitmap inside the PDF, too.
Any ideas on this?

JavaFX binding image property to image (MVC)

I stumbled upon this question while searching for an answer. But it doesn't seem to be a solution for my case.
In my viewcontroller I've the following:
public void setModel(CarcassonneModel model) {
this.model = model;
ivHoveringTile.imageProperty().bind(getImage(model.board.getActiveTile().getFilename()));
}
private ObjectProperty<Image> getImage(String filename) {
File file = new File("src/carcassonneapplicatie/resources/tiles/" + filename + ".png");
Image image = new Image(file.toURI().toString());
ObjectProperty<Image> imageProperty = new SimpleObjectProperty<>(image);
return imageProperty;
}
However, the displayed image doesn't change when I change the filename in my model using an action event. I've got other bindings for my labels and they seem to work perfectly, except for this one.
If you do
someProperty.bind(someOtherProperty);
then someProperty is updated automatically whenever someOtherProperty.set(...) is invoked.
In your code someOtherProperty is the ObjectProperty<Image> you create in your getImage() method. Since you don't even retain a reference to this property, there's no possible way you can ever call set(...) on it. So the image in ivHoveringTile never updates.
You need to bind to an observable object in the model, representing the actual value that may change.

RecyclerView lazy loading

I'm doing lazy loading on a RecyclerView adapter. First I fetch the image metadata (if it has any) and then let Picasso download the actual image.
public class PostHolder extends RecyclerView.ViewHolder implements Callback<Photo>{
private PostImageView cover;
private TextView content;
private long id;
public PostHolder(View itemView) {
super(itemView);
this.itemView.setOnClickListener(onClickListener);
content = (TextView) itemView.findViewById(R.id.post_content);
cover = (PostImageView) itemView.findViewById(R.id.post_image);
}
public void setPost(final Post post, int i){
cover.unsetImage();
this.id = post.getPhotoId();
itemView.setTag(i);
content.setText(post.getMessage());
if("photo".equals(post.getType()) || "video".equals(post.getType()) && id != 0L){
cache.get(id, this);
}else{
cover.setUrl(post.getImageUrl());
}
}
#Override
public void result(Photo result) {
if(result != null && result.getId() == PostHolder.this.id){
cover.setPhoto(result);
}
}
}
cache.get() loads my metadata from the cache, the result is returned with result().setPost() gets called in onBindViewHolder(). Now I'm getting everyone's favorite viewholder issue - my ImageView displays a different image before switching to the correct one. I know that Picasso correctly handles this and I have a check for my own loading where i compare the holder's id to the metadata id. I've spent a few hours on this already. Internet, you are my only hope.
It's fixed now, though I'm not exactly sure why. I believe it's
Picasso
.with(getContext())
.cancelRequest(this);
inside unsetImage() because of the double request needed to load it.
What I think happens:
Picasso is still loading the previous image.
A call for the current image metadata is dispatched.
Picasso loads the preVious image. Since Picasso doesn't know about the metadata, it's not automatically canceled.
The metadata get's loaded, and Picasso starts loading the current image.

Tools/Guide to Creating an Image Looper in GWT

I'm setting out to create a weather model display tool (web application), and from what I've seen, I'm really liking the idea of using Google Web Tools, and especially the SmartGWT toolkit. My one biggest sticking point at this point is finding some way to create a sort of image "looper" (displaying all images in a particular "set" one after another, not unlike a slide show). For reference, I need functionality (at least on a basic level) similar to this: http://rapidrefresh.noaa.gov/hrrrconus/jsloop.cgi?dsKeys=hrrr:&runTime=2012053007&plotName=cref_sfc&fcstInc=60&numFcsts=16&model=hrrr&ptitle=HRRR%20Model%20Fields%20-%20Experimental&maxFcstLen=15&fcstStrLen=-1&resizePlot=1&domain=full&wjet=1 (though it certainly need not be exactly like that).
Does anyone know of (ideally) some sort of GWT module that can do image looping? Or if not, does it sound like something an intermediate programmer could figure out without too much trouble (I'm willing to accept a challenge), even if I've never explicitly used GWT before? I'm sure I could whip together something that pulls each image in as it goes through a loop, but prefetching them would be even more ideal.
Please comment if you need clarification on anything!
As far as I'm aware there's not a pre-fab solution to do this, although maybe SmartGWT has something I don't know about. In any case, it won't be too hard to roll your own. Here's some code to get you started:
public class ImageLooper extends Composite {
// List of images that we will loop through
private final String[] imageUrls;
// Index of the image currently being displayed
private int currentImage = 0;
// The image element that will be displayed to the user
private final Image image = new Image();
// The Timer provides a means to execute arbitrary
// code after a delay or at regular intervals
private final Timer imageUpdateTimer = new Timer() {
public void run() {
currentImage = (currentImage + 1) % images.length;
image.setUrl(imageUrls[currentImage]);
}
}
// Constructor. I'll leave it to you how you're going to
// build your list of image urls.
public ImageLooper(String[] imageUrls) {
this.imageUrls = imageUrls;
// Prefetching the list of images.
for (String url : imageUrls)
Image.prefetch(url);
// Start by displaying the first image.
image.setUrl(imageUrls[0]);
// Initialize this Composite on the image. That means
// you can attach this ImageLooper to the page like you
// would any other Widget and it will show up as the
// image.
initWidget(image);
}
// Call this method to start the animation
public void playAnimation() {
// Update the image every two seconds
imageUpdateTimer.scheduleRepeating(2000);
}
// Call this method to stop the animation
public void stopAnimation() {
imageUpdateTimer.cancel();
}
}
One annoying thing with this implementation is that you have no way of knowing when your list of images has finished loading; Image.prefetch doesn't have a callback to help you here.

Java ME out of memory

I'm making a Java ME application for Symbian S60 5th edition and I have problem with the memory. After some time of running the app I recieve the out of memory exception.
I'm getting images from Google Maps (by the integrated GPS in Nokia 5800) and showing them.
I have this implemented like this:
class MIDlet with method setForm()
class Data which has a thread that collects info about the coordinates, gets image from Google maps, creates new form, appends the image, and calls the method setForm(f) from the Midlet.
Probable the Display.setCurrent(Form f) keeps references on the forms and like this the memory gets fast full.
I tried with Canvas but it has some stupid UI (some circle and some 4 buttons) that I don't like.
How can I solve this problem?
PS: the code...
In class MIDlet
public void setInfo(Form f)
{
getDisplay().setCurrent(f);
}
in class TouristData which collects information about location and gets map image
private attributes:
private Form f=null;
private ImageItem imageItem=null;
private Image img = null;
method locationUpdated which is called when recieve new location:
public void locationUpdated(LocationProvider provider,final Location location)
{
if (!firstLocationUpdate)
{
firstLocationUpdate = true;
statusListener.firstLocationUpdateEvent();
}
if(touristUI != null)
{
new Thread()
{
public void run()
{
if(location != null && location.isValid())
{
//lokacija je, prikaži!
try
{
QualifiedCoordinates coord =location.getQualifiedCoordinates();
if(imageItem == null)
{
imageItem = new ImageItem(null,null,0,null);
imageItem.setAltText("ni povezave");
f.append(imageItem);
}
else
{
img = googleConnector.retrieveStaticImage2(360,470, coord.getLatitude(), coord.getLongitude(), 16, "png32"); //z markerje
imageItem.setImage(img);
}
}catch(Exception e)
{}
}
else
{
}
}
}.start();
}
}
Are you keeping references to the forms or the images? These will keep them from being garbage collected and will cause out of memory errors.
It is hard to tell without some source code. Anyway, it will be better to re-architect your Midlet not to create new forms, but to reuse the same one.

Resources