I'm editing an open source app: A simple coloring page app for kids. I need to be able to make the user import his own images to be colored. Here is the full source code.
And here is the code for loading images from R.drawable:
public class StartNewActivity extends NoTitleActivity implements View.OnClickListener
{
// This is an expensive operation.
public static int randomOutlineId()
{
return new ResourceLoader().randomOutlineId();
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Apparently this cannot be set from the style.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
setContentView(R.layout.start_new);
GridView gridview = (GridView) findViewById(R.id.start_new_grid);
gridview.setAdapter(new ImageAdapter(this));
}
public void onClick(View view)
{
setResult(view.getId());
finish();
}
private static class ResourceLoader
{
ResourceLoader()
{
// Use reflection to list resource ids of thumbnails and outline
// images.First, we list all the drawables starting with the proper
// prefixes into 2 maps.
Map<String, Integer> outlineMap = new TreeMap<String, Integer>();
Map<String, Integer> thumbMap = new TreeMap<String, Integer>();
Field[] drawables = R.drawable.class.getDeclaredFields();
for (int i = 0; i < drawables.length; i++)
{
String name = drawables[i].getName();
try
{
if (name.startsWith(PREFIX_OUTLINE))
{
outlineMap.put(name.substring(PREFIX_OUTLINE.length()),
drawables[i].getInt(null));
}
if (name.startsWith(PREFIX_THUMB))
{
thumbMap.put(name.substring(PREFIX_THUMB.length()),
drawables[i].getInt(null));
}
}
catch (IllegalAccessException e)
{
}
}
Set<String> keys = outlineMap.keySet();
keys.retainAll(thumbMap.keySet());
_outlineIds = new Integer[keys.size()];
_thumbIds = new Integer[keys.size()];
int j = 0;
Iterator<String> i = keys.iterator();
while (i.hasNext())
{
String key = i.next();
_outlineIds[j] = outlineMap.get(key);
_thumbIds[j] = thumbMap.get(key);
j++;
}
}
public Integer[] getThumbIds()
{
return _thumbIds;
}
public Integer[] getOutlineIds()
{
return _outlineIds;
}
public int randomOutlineId()
{
return _outlineIds[new Random().nextInt(_outlineIds.length)];
}
private static final String PREFIX_OUTLINE = "outline";
private static final String PREFIX_THUMB = "thumb";
private Integer[] _thumbIds;
private Integer[] _outlineIds;
}
private class ImageAdapter extends BaseAdapter
{
ImageAdapter(Context c)
{
_context = c;
_resourceLoader = new ResourceLoader();
}
public int getCount()
{
return _resourceLoader.getThumbIds().length;
}
public Object getItem(int i)
{
return null;
}
public long getItemId(int i)
{
return 0;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null)
{
// If it's not recycled, initialize some attributes
imageView = new ImageView(_context);
imageView.setLayoutParams(new GridView.LayoutParams(145, 145));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
imageView.setOnClickListener(StartNewActivity.this);
}
else
{
imageView = (ImageView) convertView;
}
imageView.setImageResource(_resourceLoader.getThumbIds()[position]);
imageView.setId(_resourceLoader.getOutlineIds()[position]);
return imageView;
}
private Context _context;
private ResourceLoader _resourceLoader;
}
}
You can use File to write the imported file of the user. Use something like this.
public boolean write(byte[] data, File file)
{
if (file.getParentFile().exists()) {
if (file.exists()) {
file.delete();
}
} else {
file.getParentFile().mkdirs();
}
try{
OutputStream output = new FileOutputStream(file);
output.write(data);
output.close();
return true;
}catch(Exception e){
Log.v("FileManager", "Error writing file.", e);
return false;
}
}
Sample:
String pathName = "/mnt/sdcard/Android/data/com.company.project/files/tmp/photo.png";
Bitmap bmp = BitmapFactory.decodeFile(pathName);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
write(byteArray, new File("/mnt/sdcard/Android/data/com.company.project/files/photo.png");
Related
I am using ViewPager in my app and fetch the data(Images) from server(with JSON). Even if runs smoothly no image is shown in the viewpager.
I read so many tutorial regarding this, but nobody solve my problem. Please tell me where i am wrong...
Here is my code:
view_pager.xml
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="40dp" />
image_view.xml
<ImageView
android:id="#+id/image_adapter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"/>
ViewPager_Adapter.java
public class ViewPager_Adapter extends PagerAdapter {
private String urls;
private LayoutInflater inflater;
private Context context;
ArrayList<String> mylist;
public ViewPager_Adapter(Context context, ArrayList<String> mylist) {
this.context = context;
this.urls = urls;
this.mylist = mylist;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return mylist.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.image_view, null);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image_adapter);
Glide.with(context)
.load(mylist.get(position))
.into(imageView);
view.addView(imageLayout,0);
return imageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public Parcelable saveState() {
return null;
}
}
View_Pager.Java
public class View_Pager extends Fragment {
private static ViewPager mPager;
JSONArray responsearray = null;
String imageOne;
private static final String TAG_PHOTO_ONE = "Gallery_Full";
ArrayList<String> myList;
HashMap<String, String> get;
ViewPager_Adapter viewpager_adapter;
LinearLayout addimages;
int REQUEST_CODE = 100;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_pager, null);
mPager = view.findViewById(R.id.viewpager);
new GetImages().execute(true);
return view;
}
class GetImages extends AsyncTask<Boolean, Void, String> {
#Override
protected String doInBackground(Boolean... booleans) {
ImageApi imageApi = new ImageApi();
String result = null;
try {
result = imageApi.galleryget(sharedPreferences.getString("id", ""));
JSONObject object = new JSONObject(result);
if (object.getString("error").equalsIgnoreCase("false")) {
responsearray = object.getJSONArray("response");
return "true";
} else {
String errormsg = object.getString(result);
return errormsg;
}
} catch (ApiException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != null) {
if (s.equalsIgnoreCase("true")) {
showList(responsearray);
}
}
}
}
public void showList(final JSONArray responsearray) {
try {
for (int i = 0; i < responsearray.length(); i++) {
JSONObject responseObject = responsearray.getJSONObject(i);
Log.e("COUNT" + i, String.valueOf(responseObject));
imageOne = responseObject.getString(TAG_PHOTO_ONE);
get = new HashMap<>();
get.put(TAG_PHOTO_ONE, imageOne);
myList = new ArrayList<>();
myList.add(String.valueOf(get));
}
viewpager_adapter = new ViewPager_Adapter(getActivity(), myList);
String test = String.valueOf(myList);
String imgpath = getString(R.string.imgpath);
String finalimgpath = imgpath + imageOne;
Log.e("FINALPATH", finalimgpath);
} catch (JSONException e) {
e.printStackTrace();
}
mPager.setAdapter(viewpager_adapter);
viewpager_adapter.notifyDataSetChanged();
}
}
Use this code for showList() as you are not populating you're arrayList properly the data is being over write in one position .
So , what you have to do is initialize it out side of for loop .
public void showList(final JSONArray responsearray) {
try {
//here
myList = new ArrayList<>();
for (int i = 0; i < responsearray.length(); i++) {
JSONObject responseObject = responsearray.getJSONObject(i);
Log.e("COUNT" + i, String.valueOf(responseObject));
imageOne = responseObject.getString(TAG_PHOTO_ONE);
get = new HashMap<>();
get.put(TAG_PHOTO_ONE, imageOne);
myList.add(String.valueOf(get));
}
viewpager_adapter = new ViewPager_Adapter(getActivity(), myList);
String test = String.valueOf(myList);
String imgpath = getString(R.string.imgpath);
String finalimgpath = imgpath + imageOne;
Log.e("FINALPATH", finalimgpath);
} catch (JSONException e) {
e.printStackTrace();
}
mPager.setAdapter(viewpager_adapter);
viewpager_adapter.notifyDataSetChanged();
}
Edit
Also if your final image path is as below then you have to update your code in adapter for image path as follow.
Update position in view.addView() too.
String test = String.valueOf(mylist.get(position));
String imgpath = getString(R.string.imgpath);
String finalimgpath = imgpath + test;
Glide.with(context)
.load(finalimgpath)
.into(imageView);
view.addView(imageLayout,position);
return imageLayout;
In your For loop you are initialising your list everytime
for (int i = 0; i < responsearray.length(); i++) {
JSONObject responseObject = responsearray.getJSONObject(i);
Log.e("COUNT" + i, String.valueOf(responseObject));
imageOne = responseObject.getString(TAG_PHOTO_ONE);
get = new HashMap<>();
get.put(TAG_PHOTO_ONE, imageOne);
myList = new ArrayList<>(); // THIS IS WRONG. don't initialise every time
myList.add(String.valueOf(get)); // THIS IS ALSO WRONG. you are adding hashmap object to list
}
So make your for loop like this
myList = new ArrayList<>();
for (int i = 0; i < responsearray.length(); i++) {
JSONObject responseObject = responsearray.getJSONObject(i);
Log.e("COUNT" + i, String.valueOf(responseObject));
imageOne = responseObject.getString(TAG_PHOTO_ONE);
get = new HashMap<>();
get.put(TAG_PHOTO_ONE, imageOne);
myList.add(imageOne);
}
I'm nearly finished with my App!
It's working fine, but there's a little mistake in it..
My App is an "Note"-App with some notes that are prefabricated and are the first opening of the app.
Therefore I save this notes at the first start and get them everytime I start the app again.
Unfortunately I'm have 66 prefabricated notes and they are all saved, but in the ListView there are only 45 or so in it..
I don't think it's something with syntax because the app works fine except the loss of 21 prefabricated notes
Here's my MainActivity Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
boolean useDarkTheme = preferences.getBoolean(PREF_DARK_THEME, false);
SharedPreferences prefers = getApplicationContext().getSharedPreferences("prefs_daten", MODE_PRIVATE);
if (useDarkTheme) {
setTheme(R.style.AppTheme_dark);
}
super.onCreate(savedInstanceState);
if (VERBOSE) Log.v(TAG, "+ ON CREATE +");
setContentView(layout.activity_hauptmenu);
mListNotes = findViewById(id.listview);
itemTitel = new ArrayList<>();
itemTitel.addAll(Arrays.asList(string.Titel1, string.Titel2, string.Titel3, ...
string.Titel66));
itemStory = new ArrayList<>();
itemStory.addAll(Arrays.asList(string.Blackstory1, ...));
itemLosung = new ArrayList<>();
itemLosung.addAll(Arrays.asList(string.Losung1, ..));
}
private void StandardBS() {
if (Listensize==0){
anzahl_BS=66;
int a;
for(a=0; a<anzahl_BS; a++){
try{
tempTitel = getResources().getString(itemTitel.get(a));
tempStory = getResources().getString(itemStory.get(a));
tempLosung = getResources().getString(itemLosung.get(a));
Blackstory blackstory = new Blackstory(System.currentTimeMillis(), tempTitel, tempStory, tempLosung);
Log.w("Blackstory", ""+tempTitel);
Utilities.saveBlackstory(this, blackstory);
//Toast.makeText(this, "Blackstory wurde gespeichert!", Toast.LENGTH_SHORT).show();
}
catch (NullPointerException e){
//Toast.makeText(this, "Standard wurde falsch ausgeführt", Toast.LENGTH_SHORT).show();
}
}
Log.w("Anzahl", ""+a);
}
#Override
protected void onResume() {
super.onResume();
try{
mListNotes.setAdapter(null);
}
catch (NullPointerException e){
Toast.makeText(this, "not null", Toast.LENGTH_SHORT).show();
}
final ArrayList<Blackstory> blackstories = Utilities.getAllSavedBlackstory(getApplicationContext());
Listensize=blackstories.size();
anzahl_BS=Listensize;
if(blackstories != null && blackstories.size() > 0) { //check if we have any notes!
na = new BlackstoryAdapter(this, layout.item_layout1, blackstories);
try{
mListNotes.setAdapter(na);
}
catch (NullPointerException e){
Toast.makeText(this, "Irgendwas ist falsch2", Toast.LENGTH_SHORT).show();
}
//set click listener for items in the list, by clicking each item the note should be loaded into NoteActivity
try{
mListNotes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//run the NoteActivity in view/edit mode
fileName = ((Blackstory) mListNotes.getItemAtPosition(position)).getDateTime()
+ Utilities.FILE_EXTENSION;
Intent viewBlackstoryIntent = new Intent(getApplicationContext(), number1.class);
viewBlackstoryIntent.putExtra(Utilities.EXTRAS_NOTE_FILENAME, fileName);
startActivity(viewBlackstoryIntent);
}
});
mListNotes.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
//ask user if he really wants to delete the note!
Dialog_delete(position, id);
return true;
}});}
catch (NullPointerException e){
Toast.makeText(this, "Irgendwas ist falsch3", Toast.LENGTH_SHORT).show();
}}
else { //remind user that we have no notes!
Toast.makeText(getApplicationContext(), "you have no saved notes!\ncreate some new notes :)"
, Toast.LENGTH_SHORT).show();
}
firstOpen=false;
}
My Utilities (to save and load notes):
public class Utilities {
public static final String FILE_EXTENSION = ".bin";
public static final String EXTRAS_NOTE_FILENAME = "EXTRAS_NOTE_FILENAME";
public static boolean saveBlackstory(Context context, Blackstory blackstory){
String fileName = String.valueOf(blackstory.getDateTime()) + FILE_EXTENSION;
FileOutputStream fos;
ObjectOutputStream oos;
try{
fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(blackstory);
oos.close();
}
catch (IOException e) {
e.printStackTrace();
Log.w("Failed","");
return false;
}
return true;
}
public static ArrayList<Blackstory> getAllSavedBlackstory(Context context) {
ArrayList<Blackstory> blackstories = new ArrayList<>();
File filesDir = context.getFilesDir();
ArrayList<String> blackstoryFiles = new ArrayList<>();
int size = blackstoryFiles.size();
//add .bin files to the noteFiles list
for(String file : filesDir.list()) {
if(file.endsWith(FILE_EXTENSION)) {
blackstoryFiles.add(file);
Log.w("Included", ""+file);
}
}
//read objects and add to list of notes
FileInputStream fis;
ObjectInputStream ois;
for (int i = 0; i < blackstoryFiles.size(); i++) {
try{
fis = context.openFileInput(blackstoryFiles.get(i));
ois = new ObjectInputStream(fis);
blackstories.add((Blackstory)ois.readObject());
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
return blackstories;
}
public static Blackstory getBlackstoryByFileName(Context context, String fileName) {
File file = new File(context.getFilesDir(), fileName);
if(file.exists() && !file.isDirectory()) { //check if file actually exist
Log.v("UTILITIES", "File exist = " + fileName);
FileInputStream fis;
ObjectInputStream ois;
try { //load the file
fis = context.openFileInput(fileName);
ois = new ObjectInputStream(fis);
Blackstory note = (Blackstory) ois.readObject();
fis.close();
ois.close();
return note;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
public static boolean deleteFile(Context context, String fileName) {
File dirFiles = context.getFilesDir();
File file = new File(dirFiles, fileName);
if(file.exists() && !file.isDirectory()) {
return file.delete();
}
return false;
}
And my Adapter:
public class BlackstoryAdapter extends ArrayAdapter<Blackstory> {
public static final int WRAP_CONTENT_LENGTH = 50;
public BlackstoryAdapter(Context context, int resource, List<Blackstory> blackstories) {
super(context, resource, blackstories);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(getContext())
.inflate(R.layout.item_layout1, null);
}
Blackstory blackstory = getItem(position);
if(blackstory != null) {
TextView title = convertView.findViewById(R.id.single_titel);
title.setText(blackstory.getTitel());
}
return convertView;
}
My Blackstory.java:
public class Blackstory implements Serializable {
private String mTitel;
private String mStory;
private String mLosung;
private long mDateTime;
public Blackstory(long dateInMills, String titel, String story, String losung) {
mDateTime = dateInMills;
mTitel = titel;
mStory = story;
mLosung = losung;
}
public void setDateTime(long dateTime) {
mDateTime = dateTime;
}
public long getDateTime() {
return mDateTime;
}
public String getDateTimeFormatted(Context context) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"
, context.getResources().getConfiguration().locale);
formatter.setTimeZone(TimeZone.getDefault());
return formatter.format(new Date(mDateTime));
}
public String getTitel() {
return mTitel;
}
public void setTitel(String titel) {
mTitel = titel;
}
public String getStory() {
return mStory;
}
public void setStory(String story) {
mStory = story;
}
public String getLosung() {
return mLosung;
}
public void setLosung(String losung) {
mLosung = losung;
}
}
There need not be getCount() method as pointed out by AguThadeus. The array data is passed to the superclass so that will take care of the number of views.
So I have a Recyclerview which holding items with images, I want to load images into the items but when I do that I got a lot of fps drops.
I read that I need to use another thread for the network part and I tried to do that as you can see, and it seems good to me but I can't figure out how to stop the fps drops and make the scrolling in the Recyclerview smooth, this Recyclerview supposed to hold between 10 and 100. Am I supposed to run the activity in a thread?
Note: The fps drops occur with 10 items.
calling to the HttpWrapper.LoadImageFromWebOperations function in OnBindViewHolder.
HomeAdapter.java
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.HomeViewHolder>{
private Context context;
private ArrayList<RecipeModel> items;
public HomeAdapter(Context context, ArrayList<RecipeModel> items) {
this.context = context;
this.items = items;
}
#Override
public HomeAdapter.HomeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.home_item,null);
HomeAdapter.HomeViewHolder holder = new HomeAdapter.HomeViewHolder(v);
return holder;
}
public void addItem(RecipeModel item){
this.items.add(item);
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(HomeAdapter.HomeViewHolder holder, final int position) {
RecipeModel model = items.get(position);
holder.name.setText(model.getName());
holder.directions.setText(model.getDirections()[0]);
Drawable drawable = HttpWrapper.LoadImageFromWebOperations(model.getImageSource());
holder.image.setImageDrawable(drawable);
}
#Override
public int getItemCount() {
return items.size();
}
class HomeViewHolder extends RecyclerView.ViewHolder{
TextView name;
TextView directions;
ImageView image;
public HomeViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.recipe_name);
directions = (TextView) itemView.findViewById(R.id.recipe_directions);
image = (ImageView) itemView.findViewById(R.id.recipe_image);
}
}
HttpWrapper.java
public class HttpWrapper {
String responseMsg = "";
private OkHttpClient client;
private Request request;
public static final String base_url = "http://kingtimmy.pythonanywhere.com";
public static final String home_route = "/home/";
public HttpWrapper() {
client = new OkHttpClient();
}
public ArrayList<RecipeModel> get_home_recipes(int recipe_num){
ArrayList<RecipeModel> models = new ArrayList<RecipeModel>();
request = new Request.Builder().url(base_url + home_route + String.valueOf(recipe_num)).build();
responseMsg = "";
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
responseMsg = "Error: " + e.getMessage();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
responseMsg = response.body().string();
}
});
while(responseMsg.equals("")){
continue;
}
String[] jsons = responseMsg.split("]-]");
for (int i = 0; i < jsons.length; i++){
models.add(makeRecipeModel(jsons[i]));
}
return models;
}
public RecipeModel makeRecipeModel(String msg){
JSONObject nodeRoot = null;
RecipeModel model;
try {
nodeRoot = new JSONObject(msg);
String[] directions = nodeRoot.get("directions").toString().split("\\n");
String[] ingredients = nodeRoot.get("ingredients").toString().split("\\n");
String image_source = nodeRoot.get("image").toString();
String source_url = nodeRoot.get("source_url").toString();
String name = nodeRoot.get("name").toString();
int id = Integer.valueOf(nodeRoot.get("id").toString());
model = new RecipeModel(directions,ingredients,image_source,source_url,name,id);
} catch (JSONException e) {
model = null;
}
return model;
}
public static Drawable LoadImageFromWebOperations(final String url) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Drawable> callable = new Callable<Drawable>() {
#Override
public Drawable call() {
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
} catch (Exception e) {
System.out.println("Exc=" + e);
return null;
}
}
};
Future<Drawable> future = executor.submit(callable);
// future.get() returns 2 or raises an exception if the thread dies, so safer
try {
Drawable d = future.get();
executor.shutdown();
return d;
} catch (Exception e) {
return null;
}
}
What am I doing wrong?
Instead of writing your own thread and code to fetch, parse, decode and load the image, give Glide a try. It does all that for you with a simple single line code and loads the image in your ImageView
Im beginner and try to work on an app. I want to create a new page/activity when the imageButton on the listView is clicked. (The image is grab from url). Any help is appreciated.
Here is themain.java
public class IngredientCategoryMain extends Activity {
ListView list;
String[] title;
CategoryImageAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ingredient_category_main);
list=(ListView)findViewById(R.id.listView);
title = getResources().getStringArray(R.array.titles);
adapter=new CategoryImageAdapter(this, mStrings, title);
list.setAdapter(adapter);
}
#Override
public void onDestroy() {
list.setAdapter(null);
super.onDestroy();
}
public View.OnClickListener listener=new View.OnClickListener() {
#Override
public void onClick(View arg0) {
adapter.imageLoader.clearCache();
adapter.notifyDataSetChanged();
}
};
public void onItemClick(int mPosition) {
String tempValues = title[mPosition];
Toast.makeText(IngredientCategoryMain.this, "You have clicked "+tempValues, Toast.LENGTH_LONG).show();
}
private String[] mStrings={
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Ic_cake_48px.svg/2000px-Ic_cake_48px.svg.png",
"https://pixabay.com/static/uploads/photo/2013/04/01/21/30/can-99137_960_720.png",
"http://publicdomainvectors.org/photos/Gerald_G_Fast_Food_Drinks_(FF_Menu)_9.png",
"https://pixabay.com/static/uploads/photo/2014/03/25/16/59/apple-297775_960_720.png",
"https://pixabay.com/static/uploads/photo/2012/04/16/11/14/mortar-35544_960_720.png",
"https://pixabay.com/static/uploads/photo/2013/07/13/10/05/cattle-156498_960_720.png",
"https://pixabay.com/static/uploads/photo/2013/07/12/15/39/acorn-150258_960_720.png",
"http://publicdomainvectors.org/photos/johnny_automatic_bread_with_knife.png",
"https://pixabay.com/static/uploads/photo/2015/09/13/00/12/chicken-937584_960_720.jpg",
"http://publicdomainvectors.org/photos/bowl-of-steaming-soup-01.png",
"https://pixabay.com/static/uploads/photo/2014/04/02/10/38/fish-304097_960_720.png",
"http://publicdomainvectors.org/photos/Erbsen-lineart.png"
};
}
Adapter
public class CategoryImageAdapter extends BaseAdapter implements OnClickListener {
private Activity activity;
private String[] data;
private String[] title;
private static LayoutInflater inflater = null;
public ImageLoader imageLoader;
public CategoryImageAdapter(Activity a, String[] d, String[] t) {
activity = a;
title = t;
data = d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
#Override
public int getCount() {
return title.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public void onClick(View v) {
}
public static class ViewHolder {
public ImageButton imageButton;
public TextView textView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if (convertView == null) {
vi = inflater.inflate(R.layout.ingcategoryrow, null);
holder = new ViewHolder();
holder.textView = (TextView) vi.findViewById(R.id.textView2);
holder.imageButton = (ImageButton) vi.findViewById(R.id.imageButton2);
vi.setTag(holder);
} else
holder = (ViewHolder) vi.getTag();
holder.textView.setText(title[position]);
ImageButton imageButton = holder.imageButton;
imageLoader.DisplayImage(data[position], imageButton);
vi.setOnClickListener(new OnItemClickListener(position));
return vi;
}
private class OnItemClickListener implements OnClickListener{
private int mPosition;
OnItemClickListener(int position) {
mPosition = position;
}
#Override
public void onClick(View arg0) {
IngredientCategoryMain sct = (IngredientCategoryMain)activity;
sct.onItemClick(mPosition);
}
}
ImageLoader
public class ImageLoader {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageButton, String> imageButtons = Collections.synchronizedMap(new WeakHashMap<ImageButton, String>());
ExecutorService executorService;
Handler handler = new Handler();
public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService= Executors.newFixedThreadPool(5);
}
final int stub_id=R.drawable.bakingood;
public void DisplayImage(String url, ImageButton imageButton) {
imageButtons.put(imageButton, url);
Bitmap bitmap = memoryCache.get(url);
if(bitmap!=null) {
imageButton.setImageBitmap(bitmap);
} else {
queuePhoto(url, imageButton);
imageButton.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageButton imageButton){
PhotoToLoad p = new PhotoToLoad(url, imageButton);
executorService.submit(new PhotosLoader(p));
}
private class PhotoToLoad {
public String url;
public ImageButton imageButton;
public PhotoToLoad(String u, ImageButton i) {
url=u;
imageButton=i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad=photoToLoad;
}
#Override
public void run() {
try{
if(imageButtonReused(photoToLoad))
return;
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if(imageButtonReused(photoToLoad))
return;
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
} catch (Throwable th) {
th.printStackTrace();
}
}
}
private Bitmap getBitmap(String url) {
File f=fileCache.getFile(url);
Bitmap b= decodeFile(f);
if(b!=null)
return b;
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex) {
ex.printStackTrace();
if(ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
private Bitmap decodeFile(File f) {
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1=new FileInputStream(f);
BitmapFactory.decodeStream(stream1,null,o);
stream1.close();
//Find the correct scale value. It should be the power of 2.
// Set width/height of recreated image
final int REQUIRED_SIZE=85;
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;
}
//decode with current scale values
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
FileInputStream stream2=new FileInputStream(f);
Bitmap bitmap= BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
boolean imageButtonReused(PhotoToLoad photoToLoad){
String tag=imageButtons.get(photoToLoad.imageButton);
if (tag==null || !tag.equals(photoToLoad.url))
return true;
return false;
}
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {bitmap = b;photoToLoad = p;}
public void run() {
if (imageButtonReused(photoToLoad))
return;
if (bitmap!=null)
photoToLoad.imageButton.setImageBitmap(bitmap);
else
photoToLoad.imageButton.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
MemoryCache
public class MemoryCache {
private static final String TAG = "MemoryCache";
private Map<String, Bitmap> cache = Collections.synchronizedMap(
new LinkedHashMap<String, Bitmap>(10,1.5f, true));
private long size=0;
private long limit=1000000;
public MemoryCache () {
setLimit(Runtime.getRuntime().maxMemory() / 4);
}
public void setLimit(long limit) {
this.limit = limit;
Log.i(TAG, "MemoryCache will use up to " + limit / 1024. / 1024. + "MB");
}
public Bitmap get(String id) {
try {
if (!cache.containsKey(id))
return null;
return cache.get(id);
} catch (NullPointerException ex) {
ex.printStackTrace();
return null;
}
}
public void put(String id, Bitmap bitmap) {
try{
if(cache.containsKey(id))
size-=getSizeInBytes(cache.get(id));
cache.put(id, bitmap);
size+=getSizeInBytes(bitmap);
checkSize();
}catch (Throwable th) {
th.printStackTrace();
}
}
private void checkSize() {
Log.i(TAG, "cache size="+size+" length="+cache.size());
if(size>limit) {
Iterator<Map.Entry<String, Bitmap>> iter=cache.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Bitmap> entry=iter.next();
size-=getSizeInBytes(entry.getValue());
iter.remove();
if(size<=limit)
break;
}
Log.i(TAG, "Clean cache.New size "+cache.size());
}
}
public void clear() {
try{
cache.clear();
size=0;
}catch (NullPointerException ex) {
}
}
private long getSizeInBytes(Bitmap bitmap) {
if (bitmap==null)
return 0;
return bitmap.getRowBytes()*bitmap.getHeight();
}
}
FileCache
public class FileCache {
private File cacheDir;
public FileCache(Context context) {
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
{
//if SDCARD is mounted (SDCARD is present on device and mounted)
cacheDir = new File(
android.os.Environment.getExternalStorageDirectory(),"LazyList");
}
else
{
// if checking on simulator the create cache dir in your application context
cacheDir=context.getCacheDir();
}
if(!cacheDir.exists()){
// create cache dir in your application context
cacheDir.mkdirs();
}
}
public void clear() {
File[] files=cacheDir.listFiles();
if(files==null)
return;
for (File f:files)
f.delete();
}
public File getFile(String url) {
//Identify images by hashcode or encode by URLEncoder.encode.
String filename=String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
return f;
}
}
Utils
public class Utils {
public static void CopyStream(InputStream is, OutputStream os)
{
final int buffer_size=1024;
try {
byte[] bytes=new byte[buffer_size];
for(;;) {
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
os.write(bytes, 0, count);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
In your adapter, after this line:
ImageButton imageButton = holder.imageButton;
do something like this:
imageButton.setOnClickListener(new.View.OnClickListener(){
#Override
Public void onClick(View :)
{
Intent intent = New intent(activity, ExampleActivityName.class);
activity.startActivity(intent);
}
});
The way it works is that every view has an option to react to click events that the user performs ”on him”, all you need to do is to pass an implementation of the View.OnClickListener Interface to the View (via the setOnClickListener method) and that's it.
Second step is to start an activity which is faily easy, you need to create an intent with the current context and the class of the activity you wish to start, and than call the startActivity method from your current context.
In this case, the current context is represented by the activity reference.
add the code of 'startActivity(intent)' in your listitem.onclick - you can check which image is being clicked or also the position and then launch the appropriate activity.
after this line
ImageButton imageButton = holder.imageButton;
just add this lines of code
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activity.startActivity(new Intent(activity, YourActivityClass.class));
}
});
AI have some problems again))
I have a code which parse links from file. Into the file i have some links to forum treads. Like this:
http://vao-priut.org/image/cherepashka-metis-gollandskoi-ovcharki-s-72
http://vao-priut.org/image/taiga-s-26
and etc.
I try to parse images with this code:
class ParseMyPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
input = new URL("https://gist.githubusercontent.com/akhorevich/5b849373dc9abaf921b3/raw/18e79ab6a0c0be007a2a4590e4e176184ced311a/links");
sc = new Scanner(input.openStream());
while(sc.hasNextLine()){
String link = sc.nextLine();
doc = Jsoup.connect(link).get();
Elements names = doc.select("div.node-title");
// Elements images = doc.select("div.node div.content img");
Elements imgs = doc.select("div.node div.content img");
for (Element img : imgs) {
Element myImage = img;
String imgSrc = myImage.attr("src");
InputStream inp = new java.net.URL(imgSrc).openStream();
// Decode Bitmap
bitmap = BitmapFactory.decodeStream(inp);
}
for(Element name: names) {
mData.add(name.text());
}
if(mData.size() == 0) {
mData.add("Empty result");
}
}
} catch (IOException e) {
e.printStackTrace();
mData.clear();
mData.add("Exception: " + e.toString());
}
return text; // получаем весь текст
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
sectorC_adapter = new SectorC_Adapter(getActivity());
mListView.setAdapter(sectorC_adapter);
}
}
But it parse image only from last link and add it to all items. How can i make some images bufferedArray or something like this? Thank you!!!
P.S. I forget about my BaseAdapter:
class SectorC_Adapter extends BaseAdapter{
private Context c;
SectorC_Adapter(Context c){
this.c = c;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null){
inflater = (LayoutInflater)c
.getSystemService(c.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.sector_row, parent,false);
}else {
row = convertView;
}
tvInfo = (TextView)row.findViewById(R.id.dog_name);
tvInfo.setText(mData.get(position).toString());
dog_view = (ImageView)row.findViewById(R.id.dog_view);
dog_view.setImageBitmap(bitmap);
return row;
}
}
In here you are not adding your image to any list
for (Element img : imgs) {
Element myImage = img;
String imgSrc = myImage.attr("src");
InputStream inp = new java.net.URL(imgSrc).openStream();
// Decode Bitmap
bitmap = BitmapFactory.decodeStream(inp);
///HERE YOU SHOULD ADD YOUR BITMAP TO ALL ELEMENTS
///eg. allImages.add(bitmap); or whatever.
}
I suppose that bitmap is some sort of field that is added to your all elements so basicly only the last state will be stored. What you have to do is to add your bitmap inside for-loop.