I am working on ViewPager Concept. In ViewPager item cell contains two items such as ImageView and TextView.
Initially, i will download Blur Image and show in ViewPager cell. After this was completed, i will download HighResolution Image and show in ViewPager cell respectively.
For example, if i am looking at the first Item in ViewPager as Blur Image and in background it is downloading HighResolution image and then it must refresh the ViewPager and show the HighResolution Image in the respectively view cell.
After swiping two items and then back to the first Item, that time it shows the High Resolution Image.
So my issue is without swiping left or right, i need to refresh the current view if any changes happened in the current view.
ViewPager Activity Class:
public class ViewPagerActivity extends Activity {
ViewPager pager;
String[] _blurImageURL;
PagerAdapter _pagerAdapter;
Context _context;
ViewPagerModel vpModel = new ViewPagerModel();
ArrayList<String> lstQueue=new ArrayList<String>();
Handler _handler=new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager);
pager = (ViewPager) findViewById(R.id.pagerView);
_context = this;
_blurImageURL = new String[]{
"http://cdn.connollyphoto.nyc/wp-content/uploads/2014/06/cp_seanbell_portrait_002-800x1200.jpg",
"http://static.wixstatic.com/media/e6f301_7d57a9c0ebdf4d438f88633637aaed77.jpg_srz_930_1395_85_22_0.50_1.20_0.00_jpg_srz",
"http://a4.format-assets.com/image/private/s--TmkImGBO--/c_limit,g_center,h_1200,w_65535/a_auto,fl_keep_iptc.progressive,q_95/31336-7293530-portrait-1_jpg2.jpg",
"http://daviddodgephotography.com/wp-content/uploads/2015/03/Donna_12.jpg",
"http://a3.format-assets.com/image/private/s--W9Flct-g--/c_limit,g_center,h_1200,w_65535/a_auto,fl_keep_iptc.progressive,q_95/173355-8951465-Marvin_Portraits-005.jpg",
"http://www.leifnorman.net/wp-content/uploads/2014/10/IMG_6070.jpg",
"https://dwaynefoong.files.wordpress.com/2012/05/amin-fashion-portrait-dwayne-foong-photography.jpg",
"https://m1.behance.net/rendition/modules/117495331/hd/ce856c4a1fb4c09a5ecec05839f6ddc4.jpg",
"http://www.pcimagenetwork.com/perks/Perks%202013.jpg",
};
_pagerAdapter = new ViewPagerAdapter(_context, vpModel, this);
pager.setAdapter(_pagerAdapter);
// Calling Volley Library to Download the Image for each URLi
for (int i = 0; i < _blurImageURL.length; i++) {
String fileName = String.valueOf(i);
fileName=fileName+"_blurImg";
DownloadImages(_blurImageURL[i], fileName, true);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.view_pager, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void updateView() {
_pagerAdapter.notifyDataSetChanged();
}
public void DownloadQueue(String url_in,String fileName_in)
{
if(lstQueue.contains(fileName_in))
{
Log.i("Duplicate_Request=",fileName_in);
}
else{
lstQueue.add(fileName_in);
DownloadImages(url_in,fileName_in,false);
}
}
void DownloadImages(String imageURL_in, final String fileName_in, final boolean isBlur_in) {
ImageRequest imageRequest = new ImageRequest(imageURL_in,
new Response.Listener<Bitmap>() {
#Override
public void onResponse(final Bitmap response) {
try {
Log.v("Response_Received =",fileName_in);
// Saved in SD Card and getting the Path
String imagePath = SavedInSDCard(response,fileName_in);
//updating the Model
if (isBlur_in) {
vpModel.blurImgLocalPath.add(imagePath);
} else {
vpModel.highResolutionImgLocalPath.add(imagePath);
}
//updating the View
_handler.post(new Runnable() {
#Override
public void run () {
updateView();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, 0, null, null);
ApplicationController.getInstance().addToRequestQueue(imageRequest);
}
public String SavedInSDCard(Bitmap bitmap, String fileName_in) {
File dir = new File(ApplicationController.getAppContext()
.getExternalFilesDir("ViewPager_POC") + "/Cache");
// Create the storage directory if it does not exist
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, fileName_in);
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
String imgPath = dir + "/" + fileName_in;
return imgPath;
}
}
ViewPager Adapter Class:
public class ViewPagerAdapter extends PagerAdapter {
Context _context;
LayoutInflater inflater;
ViewPagerActivity _vpActivity;
String[] _highResolutionURL = new String[]{
"http://www.monportraitpro.fr/wp-content/uploads/2014/08/Philippe-Vasilescu.jpg",
"http://www.markhicksphotography.com/wp-content/uploads/2012/01/MHP2012_01_04_MHP_DSC0003.jpg",
"http://www.andrew-mason.com/wp-content/uploads/2013/05/portrait-1-3.jpg",
"http://shutterfinger.typepad.com/.a/6a00e551a6244a8833019affd0eb14970d-pi",
"http://www.antonioolmos.com/data/photos/90_1childs_livebooks.jpg",
"http://www.dvdsreleasedates.com/pictures/800/12000/Zachary-Quinto.jpg",
"http://www.glnphotography.com/wp-content/uploads/2013/09/IMG_1347.jpg",
"http://www.dvdsreleasedates.com/pictures/800/12000/Paul-Walker.jpg",
"http://www.antonioolmos.com/data/photos/89_1blairbooks.jpg",
};
ArrayList<String> _blurImgPath;
ArrayList<String> _highResolutionImgPath;
public ViewPagerAdapter(Context context_in, ViewPagerModel vpModel_in, ViewPagerActivity activity_in) {
_context = context_in;
_blurImgPath = vpModel_in.blurImgLocalPath;
_highResolutionImgPath = vpModel_in.highResolutionImgLocalPath;
_vpActivity = activity_in;
}
#Override
public int getCount() {
return _blurImgPath.size();
}
#Override
public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
((ViewPager) container).removeView((View) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
// Declare Variables
TextView txtCounter;
final ImageView imgView;
inflater = (LayoutInflater) _context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.view_pager_item, container,
false);
txtCounter = (TextView) itemView.findViewById(R.id.counter);
imgView = (ImageView) itemView.findViewById(R.id.images);
//Setting the values for Image and textview
txtCounter.setText("" + (position + 1));
//Setting the Image
if (position < _highResolutionImgPath.size()) {
//Setting Hi-ResImage
Log.v("HighRes_ImgPath=", "Get Image from Model" );
imgView.setImageBitmap(BitmapFactory.decodeFile(_highResolutionImgPath.get(position)));
} else {
// Generating the request for HighResolution Image
String fileName = String.valueOf(position + 10);
fileName = fileName + "_clearImg";
Log.v("HighRes_ImgPath=", "Sending Request to Queue=" + fileName);
_vpActivity.DownloadQueue(_highResolutionURL[position], fileName);
//Setting the BlurImage
imgView.setImageBitmap(BitmapFactory.decodeFile(_blurImgPath.get(position)));
}
// Add viewpager_item.xml to ViewPager
((ViewPager) container).addView(itemView);
return itemView;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
}
ViewPager Model:
public class ViewPagerModel {
ArrayList<String> blurImgLocalPath=new ArrayList<String>();
ArrayList<String> highResolutionImgLocalPath=new ArrayList<String>();
}
activity_view_pager.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"
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="com.example.poc_viewpager.ViewPagerActivity" >
<android.support.v4.view.ViewPager
android:id="#+id/pagerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
/>
view_pager_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/images"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="43dp" />
</RelativeLayout>
In this case, I would use Picasso :
For example :
Picasso.with(getActivity())
.load(URL_THUMBNAIL) // thumbnail url goes here
.into(IMAGEVIEW, new Callback() { // Your image view
// On success start loading the full resolution image
#Override
public void onSuccess() {
Picasso.with(getActivity())
.load(FULL_RESOLUTION_URL) // image url goes here
.into(IMAGEVIEW);
}
#Override
public void onError() {
// Manage downloading errors here
}
});
The updateView()is called on the background thread. notifyDataSetChanged() does not work on the background thread. Call the notifyDataSetChanged() method on the UI thread and it should solve your problem
Related
I have a basket icon with count notification on it in actionbar for showing number of goods in shopping basket. also I have a custom view containing a button for add goods to shopping basket. I want that when I click on button (in custom view) notification count on basket icon increases. I use this function in main activity to update notification count but notification does not update.
public static void updateCountBasket(final int number , int id , View view ,Context context) {
if (view.findViewById(id) == null)
return;
TextView t = (TextView)view.findViewById(id);
String dd = t.getText().toString();
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
if (number == 0)
t.setVisibility(View.INVISIBLE);
else {
t.setVisibility(View.VISIBLE);
t.setText(Integer.toString(number));
}
}
});
}
but when I use non static of that function in main activity with simple button on click, it works fine. but I can't call non static function in base adapter too :( . I checked line by line of the function in static mode all ids are right and it set text too but nothing change or get error!!. please help me to change textview as notification of basket in menubar from base adapter when button in custom view clicks. thanks
I have this base adapter for my custom view list:
public class Goods_ImageAdapter extends BaseAdapter {
private Context context;
private final JSONArray Goods;
private Bagde bagde;
public Goods_ImageAdapter(Context context , JSONArray Goods) {
this.context = context;
this.Goods = Goods;
bagde = Bagde.getInstance();
}
#Override
public int getCount() {
return Goods.length();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int arg0) {
return 0;
}
public static String doubleToStringNoDecimal(double d) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);;
formatter .applyPattern("#,###");
return formatter.format(d);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
final View bagde_c;
if (convertView == null) {
gridView = new View(context);
gridView = inflater.inflate(R.layout.goodsitem, null);
bagde_c = inflater.inflate(R.layout.badge_counter, null);
try {
TextView goods_textview_Name = (TextView) gridView.findViewById(R.id.goods_textview_Name);
goods_textview_Name.setText(Goods.getJSONObject(position).getString("Name"));
TextView goods_textview_Price = (TextView) gridView.findViewById(R.id.goods_textview_Price);
goods_textview_Price.setText(Goods.getJSONObject(position).getString("Price"));
} catch (JSONException e) {
e.printStackTrace();
}
try {
ImageView goods_imageview = (ImageView) gridView.findViewById(R.id.goods_imageview);
new ImageDownloader(goods_imageview).execute("http://IP/" + Goods.getJSONObject(position).getString("ImageFileName"));
} catch (JSONException e) {
e.printStackTrace();
}
final TextView goods_textview_bagdecounter = (TextView) gridView.findViewById(R.id.goods_textview_bagdecounter);
ImageView goods_buy_plus = (ImageView) gridView.findViewById(R.id.goods_buy_button_plus);
try {
goods_buy_plus.setTag(Goods.getJSONObject(position));
} catch (JSONException e) {
e.printStackTrace();
}
goods_buy_plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
String bagde_counter_text = goods_textview_bagdecounter.getText().toString();
goods_textview_bagdecounter.setText(String.valueOf(Integer.parseInt(bagde_counter_text) + 1));
}
});
com.???.????.Goods_Activity.updateCountBasket(a number for example,R.id.notif,inflater2.inflate(R.layout.badge_counter, null),context);
}
});
ImageView goods_buy_minus = (ImageView) gridView.findViewById(R.id.goods_buy_button_minus);
try {
goods_buy_minus.setTag(Goods.getJSONObject(position));
} catch (JSONException e) {
e.printStackTrace();
}
goods_buy_minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
String bagde_counter_text = goods_textview_bagdecounter.getText().toString();
if(Integer.parseInt(bagde_counter_text)> 0)
goods_textview_bagdecounter.setText(String.valueOf(Integer.parseInt(bagde_counter_text) - 1));
}
});
}
});
} else {
gridView = (View) convertView;
}
return gridView;
}
}
this is (basket with notification on action bar) badge_counter.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/badge_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/relative_layout_item_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button"
android:layout_width="40dip"
android:layout_height="40dip"
android:background="#drawable/download" />
<TextView
android:id="#+id/notif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#android:drawable/ic_notification_overlay"
android:text="33"
android:textColor="#FFA"
android:textSize="12sp"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
You can achieve this by using interface.
Add an interface in Adapter class
public interface AdapterCallBack
{
public void onChangeBadgeCount();
}
And in constructor, pass a reference to this interface.
public Goods_ImageAdapter(Context context , JSONArray Goods, AdapterCallBack adapterCallback)
{
this.context = context;
this.Goods = Goods;
this.adapterCallback = adapterCallback;
bagde = Bagde.getInstance();
}
And whenever you want to set badge count in ActionBar, just call adapterCallback.onChangeBadgeCount().
And implement this interface in MainActivity.
public class MainActivity implements Goods_ImageAdapter.AdapterCallBack
{
... some code
When your are initializing adapter, just pass this as a last parameter.
Example:
adapter = new Goods_ImageAdapter(this, Goods /* Json data */, this);
...
#override
public void onChangeBadgeCount()
{
// Change your badge count here
}
}
I am printing my array length size in ActionBar from Recycler adapter
((Show_request) mContext).getSupportActionBar().setTitle("Total Stone:- " + array.length());
Using this you can get ActionBar in RecyclerView adapter
((your activity name) context object).getSupportActionBar().setTitle("message"/or pass variable);
I am trying to dial numbers from my app by clicking on different CardViews but its not working for me.
Everytime i tried adding an intent, the startActivity turns Red and pops out error message "cannot resolve method".
I even tried adding context before the startActivity() But it crashes the app.
I have 4 CardViews to be clicked in order to initiate a call and
I have 3 Java classes: CardViewDataAdapter where the recyclerView Holder was declared, MainActivity and itemObject
In activity_main i used recycler_view. In cardview_row i used card_view and bind it with recycler view.
Please kindly help me, i have googled this problem and also looked it up on stack overflow but no solution found yet.
The error message image
CardViewDataAdapter.java code:
public class CardViewDataAdapter extends RecyclerView.Adapter<CardViewDataAdapter.ViewHolder> {
private List<ItemObject> itemList;
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
// each data item is a string and an image in this case
public ImageView image_view;
public TextView image_name;
private Context context;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
this.image_view = (ImageView) itemLayoutView.findViewById(R.id.image_view);
this.image_name = (TextView) itemLayoutView.findViewById(R.id.image_name);
// Store the context
this.context = context;
// Attach a click listener to the entire row view
itemLayoutView.setOnClickListener(this);
}
// Handles the row being being clicked
#Override
public void onClick(View view) {
if (getPosition() == 0){
Intent callIntent = new Intent(Intent.ACTION_DIAL);
callIntent.setData(Uri.parse("tel:123456789"));
startActivity(callIntent);
} else if (getPosition() == 1){
Toast.makeText(view.getContext(), "position2 = " + getPosition(), Toast.LENGTH_SHORT).show();
} else if (getPosition() == 2){
Toast.makeText(view.getContext(), "position3 = " + getPosition(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(view.getContext(), "position4 = " + getPosition(), Toast.LENGTH_SHORT).show();
}
//context.startActivity(intent);
}
}
// Create new views (invoked by the layout manager)
#Override
public CardViewDataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.cardview_row, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
// - get data from your itemsData at this position
// - replace the contents of the view with that itemsData
viewHolder.image_view.setImageResource(itemList.get(position).getPhoto());
viewHolder.image_name.setText(itemList.get(position).getName());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return this.itemList.size();
}
public CardViewDataAdapter(Context context, List<ItemObject> itemList) {
this.itemList = itemList;
}
}
MainActivity.java code:
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a GridLayout manager
mLayoutManager = new GridLayoutManager(this, 2);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter
List<ItemObject> rowListItem = getAllItemList();
mAdapter = new CardViewDataAdapter(MainActivity.this, rowListItem);
mRecyclerView.setAdapter(mAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
Toast.makeText(getApplicationContext(), "Settings Clicked",
Toast.LENGTH_SHORT).show();
return true;
/* } else if (id == R.id.action_search) {
Toast.makeText(getApplicationContext(), "Search Clicked",
Toast.LENGTH_SHORT).show();
return true;*/
}
return super.onOptionsItemSelected(item);
}
//Handles the references to items displayed on each cards
private List<ItemObject> getAllItemList() {
List<ItemObject> allItems = new ArrayList<ItemObject>();
allItems.add(new ItemObject("Fire", R.drawable.fire));
allItems.add(new ItemObject("Ambulance", R.drawable.ambulance));
allItems.add(new ItemObject("Police", R.drawable.police));
allItems.add(new ItemObject("AntiSquad", R.drawable.police));
return allItems;
}
}
itemsObject.java code:
public class ItemObject {
private String name;
private int photo;
public ItemObject(String name, int photo) {
this.name = name;
this.photo = photo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPhoto() {
return photo;
}
public void setPhoto(int photo) {
this.photo = photo;
}
}
cardview_row.xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- CardView with customized attributes -->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="170dp"
android:layout_gravity="center_horizontal"
android:layout_margin="10dp"
cardview:cardCornerRadius="20dp"
cardview:cardElevation="90dp"
android:elevation="2dp"
android:background="#drawable/myrect"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:id="#+id/image_view"
android:layout_width="fill_parent"
android:layout_height="120dp"
/>
<TextView
android:id="#+id/image_name"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#4757b3"
android:textColor="#android:color/white"
android:fontFamily="sans-serif-condensed"
android:textSize="20sp"
android:textAlignment="center" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Looks like you have a Context issue.
To get the context you need to alter your code to as below:
Intent callIntent = new Intent(Intent.ACTION_DIAL);
callIntent.setData(Uri.parse("tel:123456789"));
view.getContext().startActivity(callIntent);
Try this :
btnTelephone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Call 1st phone number api
Uri callIntentUri = Uri.parse("tel:"+telephoneStringForCall);
Intent callIntent = new Intent(Intent.ACTION_DIAL, callIntentUri);
startActivity(callIntent);
}
});
and check your views initialisation mb you lost something
I'm using Picasso to load all my images in a Gridview and DBFlow to save in the Local database. But I have a problem when I download the images for the first time and if I'm scrolling in the gridview. The next images have the previous images and 1 second later the good image is loaded. I have to scroll 5 times or more and when all images is loaded I don't have this problem but for the first time yes.
Have you an idea to optimize my code ?
Gridview
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="130dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="#color/colorAppBackground"/>
Item Grid
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="130dp">
<ImageView
android:id="#+id/iv_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<TextView
android:id="#+id/text_thumb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:textColor="#android:color/white"
android:background="#99000000"/>
</RelativeLayout>
Activity
public class GalleryActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
Bundle bundle = getIntent().getExtras();
int idAccount = bundle.getInt("idAccount");
callAdminPictures(idAccount);
}
public void callAdminPictures(final int idAccount){
// Build REST Adapter
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Globals.SERVER_NAME)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
// Create the App Service
ApplicationService appService = restAdapter.create(ApplicationService.class);
// Call Get admin pictures WS
Call<AdminPictures> getAdminPicturesWS = appService.getAdminPictures(idAccount);
getAdminPicturesWS.enqueue(new Callback<AdminPictures>() {
#Override
public void onResponse(Call<AdminPictures> call, Response<AdminPictures> response) {
AdminPictures apResponse = response.body();
List<PictureInfos> pictureInfos = apResponse.getPicturesList();
for (PictureInfos infos : pictureInfos) {
if (infos.exists()) {
infos.update();
} else {
infos.save();
}
}
List<PictureInfos> tablePictureInfos = new Select()
.from(PictureInfos.class)
.where(PictureInfos_Table.idAccount.is("" + idAccount))
.orderBy(PictureInfos_Table.idPicture, false)
.queryList();
GridView gridView = (GridView) findViewById(R.id.gridview);
gridView.setAdapter(new ImageAdapter(GalleryActivity.this, tablePictureInfos));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(GalleryActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onFailure(Call<AdminPictures> call, Throwable t) {
if (t.getMessage() != null) {
Log.e("AdminPictures WS Fail", t.getMessage());
}
}
});
}
Adapter
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mLayoutInflater;
private List<PictureInfos> mPInfoList;
private boolean mToSave;
public ImageAdapter(Context context, List<PictureInfos> pInfoList) {
mContext = context;
mPInfoList = pInfoList;
mLayoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return mPInfoList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view;
final ImageView imageView;
final TextView legend;
if(convertView == null){
view = mLayoutInflater.inflate(R.layout.thumbnail_gallery, parent, false);
}else{
view = convertView;
}
imageView = (ImageView) view.findViewById(R.id.iv_thumbnail);
legend = (TextView) view.findViewById(R.id.text_thumb);
final File file = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), mPInfoList.get(position).getFilename());
mToSave = !file.exists();
Target target = new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
if(mToSave) {
new Thread(new Runnable() {
#Override
public void run() {
try {
FileOutputStream fileOutput = new FileOutputStream(file);
Log.i("catch", mPInfoList.get(position).getFilename());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutput);
fileOutput.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
imageView.setImageBitmap(bitmap);
if (mPInfoList.get(position).getFilename() != null) {
legend.setText(mPInfoList.get(position).getLegend());
}
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
String pic = Globals.SERVER_NAME+Globals
.ACCOUNT_SERVER_PATH+mPInfoList
.get(position).getFolderPath()+"/"+
VgzTools.addSuffix(mPInfoList.get(position).getFilename(), "-thumb");
imageView.setTag(target);
if(!file.exists()){
Picasso.with(mContext)
.load(pic)
.into(target);
mToSave = true;
}else{
Picasso.with(mContext)
.load(file)
.into(target);
mToSave = false;
}
return view;
}
Inside getView() put this line
imageView.setImageDrawable(null);
The previous image is coming because of view recycling. For each item you don't always get a new view, instead views are recycled to save memory. So once you scrolled the initially visible items, you will get the view from previous item which already has image set in it. So you have to remove it explicitly.
My guess is that because you're not explicitly clearing the imageView in your getView(), it's retaining the current image when it's recycled (IE - when it's passed in as convertView). Picasso will eventually call onBitmapLoaded(), but until then, you're left with the 'old' image.
Try explicitly clearing the image.
I want to use preloader image in gridview for images when its loading form the remote server.
while its loading from the server at that time i want to show preloader image like this(same like progress bar or progress bar).
I want to show small progress bar there in gridview image item or preloader image I dnt know what i can use which would be easily for me to achieve this.
Can anybody please help me how can do this thing in android.
I want to make this as like IOS. this image is form the IOS.
Here is my android layout xml file :
activity_image_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<include
android:id="#+id/title_bar"
android:layout_alignParentTop="true"
layout="#layout/activity_top_header_bar" />
<GridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#id/title_bar"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="4"
android:padding="5dip"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip" />
</RelativeLayout>
This xml file used for item for each grid in Gridview.
item_grid_image.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="75dp"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:scaleType="centerCrop" />
Source code :
public class ImageGridActivity extends BaseActivity {
private static final String TAG = "[ImageGridActivity]";
private DisplayImageOptions options;
private PullToRefreshGridView mPullRefreshGridView;
private GridView mGridView = null;
ArrayList<GallaryImage> mGridViewImagesList;
private ImageAdapter mImageAdapter = null;
private String mImageUrl = null;
private String mGallaryTitle = null;
// private ImageLoader imageLoader = ImageLoader.getInstance();
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_grid);
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.photo_default)
.showImageForEmptyUri(R.drawable.photo_default)
.showImageOnFail(R.drawable.ic_error).cacheInMemory()
.cacheOnDisc().bitmapConfig(Bitmap.Config.RGB_565).build();
final Bundle bundle = getIntent().getExtras();
if (bundle != null) {
mImageUrl = bundle.getString(Constants.GALLARY_FETCH_URL);
mGallaryTitle = bundle.getString(Constants.GALLARY_TYPE);
if (mGallaryTitle != null) {
Locale loc = Locale.getDefault();
TextView tvTitleText = (TextView) findViewById(R.id.tv_title_bar_text);
tvTitleText.setText(mGallaryTitle.toUpperCase(loc));
}
mPullRefreshGridView = (PullToRefreshGridView) findViewById(R.id.pull_refresh_grid);
mPullRefreshGridView.setMode(Mode.PULL_FROM_START);
mGridView = mPullRefreshGridView.getRefreshableView();
mGridViewImagesList = Utility.getImagesList(mImageUrl,
ImageGridActivity.this);
if (mGridViewImagesList != null && !mGridViewImagesList.isEmpty()) {
mImageAdapter = new ImageAdapter(mGridViewImagesList);
((GridView) mGridView).setAdapter(mImageAdapter);
} else {
// did refresh after the previous images are loaded in the
// gridview.
if (Utility.checkConnection(ImageGridActivity.this)) {
Log.i(TAG,
"Wifi/Internet Connection found , have to parse the xml");
final FetchImagesAsyncTaskFeed asyncTask = new FetchImagesAsyncTaskFeed();
asyncTask.execute(mImageUrl);
}
}
mGridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(final AdapterView<?> parent,
final View view, final int position, final long id) {
if (mGridViewImagesList != null
&& !mGridViewImagesList.isEmpty()) {
startImagePagerActivity(mGridViewImagesList, position);
} else {
Log.d(TAG, "There is no image about this grid image");
}
}
});
// Set a listener to be invoked when the list should be refreshed.
mPullRefreshGridView
.setOnRefreshListener(new OnRefreshListener2<GridView>() {
#Override
public void onPullDownToRefresh(
PullToRefreshBase<GridView> refreshView) {
if (mImageUrl != null) {
final FetchImagesAsyncTaskFeed asyncTask = new FetchImagesAsyncTaskFeed();
asyncTask.execute(mImageUrl);
}
}
#Override
public void onPullUpToRefresh(
PullToRefreshBase<GridView> refreshView) {
}
});
}
}
/**
* #param position
*/
private void startImagePagerActivity(
final ArrayList<GallaryImage> mImageAttributesList,
final int position) {
String[] urls = new String[mImageAttributesList.size()];
final Intent intent = new Intent(this, ImagePagerActivity.class);
intent.putExtra(Constants.GALLARY_IMAGE_POSITION_BUNDLE_KEY, position);
for (int i = 0; i < mImageAttributesList.size(); i++) {
urls[i] = mImageAttributesList.get(i).mImageUrl;
}
intent.putExtra(Constants.GALLARY_IMAGES_IMAGE_BUNDLE_KEY, urls);
startActivity(intent);
}
public class ImageAdapter extends BaseAdapter {
ArrayList<GallaryImage> imageList = null;
public ImageAdapter(final ArrayList<GallaryImage> imageAttributesList) {
this.imageList = imageAttributesList;
}
#Override
public int getCount() {
return imageList.size();
}
#Override
public Object getItem(final int position) {
return imageList.get(position);
}
#Override
public long getItemId(final int position) {
return position;
}
#Override
public View getView(final int position, final View convertView,
final ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(
R.layout.item_grid_image, parent, false);
} else {
imageView = (ImageView) convertView;
}
imageLoader.displayImage(imageList.get(position).mImageUrl,
imageView, options);
return imageView;
}
/**
* #param updateData
*/
public void updatedData(ArrayList<GallaryImage> imgList) {
this.imageList = imgList;
notifyDataSetChanged();
}
}
private class FetchImagesAsyncTaskFeed extends
AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(final String... urls) {
try {
Thread.sleep(3000);
final String imageUrl = urls[0];
final GridViewImagesXMLHandler mGallaryXMLHandler = new GridViewImagesXMLHandler();
mGridViewImagesList = mGallaryXMLHandler.getImages(imageUrl);
if (mGridViewImagesList != null
&& !mGridViewImagesList.isEmpty()) {
Utility.setImagesInfromation(imageUrl, mGridViewImagesList,
ImageGridActivity.this);
}
} catch (final Exception e) {
Log.e(TAG, "Exception in fetch images from the url", e);
}
return null;
}
#Override
protected void onPostExecute(final String result) {
if (mGridViewImagesList != null && !mGridViewImagesList.isEmpty()) {
if (mImageAdapter != null) {
mImageAdapter.updatedData(mGridViewImagesList);
mPullRefreshGridView.onRefreshComplete();
} else {
mImageAdapter = new ImageAdapter(mGridViewImagesList);
((GridView) mGridView).setAdapter(mImageAdapter);
}
}
mPullRefreshGridView.onRefreshComplete();
}
}
}
Universal ImageLoader
https://github.com/nostra13/Android-Universal-Image-Loader
rowimage.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/ivv"
android:layout_gravity="center"
android:layout_width="300dp"
android:layout_height="300dp"
/>
<ProgressBar
android:id="#+id/pb"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
In your adapter constructor
ImageLoader imageLoader;
DisplayImageOptions options;
File cacheDir = StorageUtils.getOwnCacheDirectory(a, "MyRaghu");
// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
// You can pass your own memory cache implementation
.discCacheExtraOptions(1024, 1024, CompressFormat.PNG, 100)
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.enableLogging()
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
//imageLoader.init(ImageLoaderConfiguration.createDefault(a));
// imageLoader=new ImageLoader(activity.getApplicationContext());
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_launcher)
.cacheInMemory()
.cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(20))
.build();
In your getview of your custom adapter
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.rowimage, null);
ImageView image=(ImageView)vi.findViewById(R.id.ivv);
ProgressBar pb= (ProgressBar)vi.findViewById(R.id.pb);
display(null, data.get(position).toString(), pb);
//imageLoader.displayImage(data.get(position).toString(), image,options);
return vi;
}
public void display(ImageView img, String url, final ProgressBar spinner)
{
imageLoader.displayImage(url, img, options, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
spinner.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
spinner.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
}
Resulting snap shot i have used listview but it should work for gridview also.
First a stub image is displayed along with progress bar. In this case a i have used a launcher icon so it looks stretched
Once image is downloaded progress bar is dismissed and stub image is replaced by the downloaded one. Even caches images.
Try to use Android-Universal-Image-Loader api from github.com
Android-Universal-Image-Loader
I think it help you.
Thanks.
I am using view pager in my activity.I created views for 7 pages. Now i want to access page view inside my activity. I am getting data as blank.
In Activity
public class ActivitySingleEntry extends Activity implements OnClickListener {
private ViewPager mPager;
private FixedTabsView mFixedTabs;
private ExamplePagerAdapter mPagerAdapter;
private TabsAdapter mFixedTabsAdapter;
private EditText edtFieldName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fixed_tabs);
initViewPager(7, 0xFFFFFFFF, 0xFF000000);
mFixedTabs = (FixedTabsView) findViewById(R.id.fixed_tabs);
mFixedTabsAdapter = new FixedTabsAdapter(this);
mFixedTabs.setAdapter(mFixedTabsAdapter);
mFixedTabs.setViewPager(mPager);
}
private void initViewPager(int pageCount, int backgroundColor, int textColor) {
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ExamplePagerAdapter(this, pageCount,
backgroundColor, textColor);
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(1);
mPager.setPageMargin(5);
}
#Override
public void onClick(View v) {
// LinearLayout lin=(LinearLayout) mPager.getChildAt(mPager.getCurrentItem());
// edtFieldName=(EditText) lin.findViewById(R.id.edtFieldName);
// Log.d("test", "From get child:"+edtFieldName.getText().toString()+":");
Log.d("test", "Current Page:"+mPager.getCurrentItem());
LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem());
edtFieldName=(EditText) linearLayout.findViewById(R.id.edtFieldName);
edtFieldName=(EditText) findViewById(R.id.edtFieldName);
if (edtFieldName==null) {
ShowToast.makeToast(getApplicationContext(), "Edt null");
}else
ShowToast.makeToast(getApplicationContext(),
"Data saved " + edtFieldName.getText().toString() + ":"
+ mPager.getCurrentItem());
}
}
My PageAdaper
public class ExamplePagerAdapter extends PagerAdapter {
protected transient Activity mContext;
private int mLength = 0;
private int mBackgroundColor = 0xFFFFFFFF;
private int mTextColor = 0xFF000000;
private String[] mData = { "Temperature", "Sugar", "BP", "Field 4",
"Field 5", "Field 6", "Field 7" };
public ExamplePagerAdapter(Activity context, int length,
int backgroundColor, int textColor) {
mContext = context;
mLength = length;
mBackgroundColor = backgroundColor;
mTextColor = textColor;
}
#Override
public int getCount() {
return mLength;
}
#Override
public Object instantiateItem(View container, int position) {
LinearLayout linearLayout = (LinearLayout) View.inflate(mContext,
R.layout.activity_single_entry, null);
TextView txtFieldName = (TextView) linearLayout
.findViewById(R.id.txtFieldName);
EditText edtFieldName = (EditText) linearLayout
.findViewById(R.id.edtFieldName);
String filedName = mData[position];
txtFieldName.setText(filedName);
edtFieldName.setHint("Please enter " + filedName);
edtFieldName.setInputType(InputType.TYPE_CLASS_TEXT);
if (filedName.equals("Temperature")) {
edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
} else if (filedName.equals("Sugar")) {
edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
} else if (filedName.equals("BP")) {
edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
}
edtFieldName.setTag("edt");
((ViewPager) container).addView(linearLayout, 0);
linearLayout.setTag("lin"+position);
Log.d("test", "Adapter creating item:"+position );
return linearLayout;
}
#Override
public void destroyItem(View container, int position, Object view) {
((ViewPager) container).removeView((View) view);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
#Override
public void finishUpdate(View container) {
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate(View container) {
}
}
In R.layout.activity_single_entry xml i have edittext and button with onclick.
MYXml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/txtFieldName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<EditText
android:id="#+id/edtFieldName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:hint="Please enter field value" />
</LinearLayout>
<Button
android:id="#+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Save"
android:layout_margin="20dp"
android:onClick="onClick"
/>
</LinearLayout>
If i used inside pageadapter
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
OnClick of button i want to access data from edit text.
I able to get value for first page.Not for all.
firstm you setTag():
linearLayout.setTag("lin"+position);
where position is in <0..numPages-1>
but read it:
LinearLayout linearLayout=(LinearLayout) mPager.findViewWithTag("lin"+mPager.getCurrentItem());
is findViewWithTag returning null everywhere or only on the last page?
mPager.getCurrentItem() returns 0 if it is first page so there is no need to add +1 while reading
In page adapter i am using single view in each page so its refers to only first item.If i tried to get view for page its giving me only first object so i applied distinct id for edit text in each page.
In page adapter
#Override
public Object instantiateItem(View container, int position) {
LinearLayout linearLayout = (LinearLayout) View.inflate(mContext,
R.layout.activity_single_entry, null);
TextView txtFieldName = (TextView) linearLayout
.findViewById(R.id.txtFieldName);
EditText edtFieldName = (EditText) linearLayout
.findViewById(R.id.edtFieldName);
***edtFieldName.setId(position);***
String filedName = mData[position];
txtFieldName.setText(filedName);
edtFieldName.setHint("Please enter " + filedName);
edtFieldName.setInputType(InputType.TYPE_CLASS_TEXT);
if (filedName.equals("Temperature")) {
edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
} else if (filedName.equals("Sugar")) {
edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
} else if (filedName.equals("BP")) {
edtFieldName.setInputType(InputType.TYPE_CLASS_NUMBER);
}
edtFieldName.setTag("edt"+position);
((ViewPager) container).addView(linearLayout, 0);
mItems.add(linearLayout);
linearLayout.setTag("lin"+position);
Log.d("test", "Adapter creating item:"+position );
return linearLayout;
}
Its working now
A quick solution would be to keep a List in your ExamplePagerAdapter and add to it after your addView() call. Then you could implement a public function such as getItemAtPosition(int position) that returns the LinearLayout at that page of the ViewPager. Then you can run findViewById(R.id.edtFieldName) on that linear layout in your Activity. In code:
In your ExamplePagerAdapter, add a private object:
List<LinearLayout> mItems;
add in your constructor:
mItems = new Vector<LinearLayout>();
add in instantiateItem():
((ViewPager) container).addView(linearLayout, 0);
mItems.add(linearLayout);
then add a method:
public LinearLayout getItemAtPosition(int position) {
return mItems.get(position);
}
Then use that method in your Activity. Hope it's what you were looking for.