I can't find a solution for my problem. I have a gridview with layouts. The layouts contains an imageview and a textview. What I need is to animate the imageview when I touch an item. How can I detect the on item keydown event in the gridview?
Here is my adapter:
public class GridViewAdapter extends BaseAdapter {
private ArrayList<SingleButton> buttons;
private MainActivity mainActivity;
public GridViewAdapter(MainActivity mainActivity) {
this.mainActivity = mainActivity;
this.buttons = new ArrayList<SingleButton>();
Resources res = mainActivity.getApplicationContext().getResources();
String[] temp = res.getStringArray(R.array.buttons);
int[] buttonImages = { R.drawable.pic1, R.drawable.pic2,
R.drawable.pic3, R.drawable.pic4, R.drawable.pic5,
R.drawable.pic6, R.drawable.pic7, R.drawable.pic8,
R.drawable.pic9 };
for (int count = 0; count < 9; ++count) {
this.buttons
.add(new SingleButton(buttonImages[count], temp[count]));
}
}
#Override
public int getCount() {
return this.buttons.size();
}
#Override
public Object getItem(int position) {
return this.buttons.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint("ViewHolder")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
LayoutInflater layoutInflater = (LayoutInflater) mainActivity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.single_button, parent, false);
holder = new ViewHolder(row);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
holder.buttonImage.setImageResource(buttons.get(position).image);
holder.buttonText.setText(buttons.get(position).buttonText);
return row;
}
class ViewHolder {
ImageView buttonImage;
TextView buttonText;
public ViewHolder(View v) {
this.buttonImage = (ImageView) v.findViewById(R.id.imageViewButton);
this.buttonText = (TextView) v.findViewById(R.id.textViewButton);
}
}
class SingleButton {
int image;
String buttonText;
SingleButton(int image, String buttonText) {
this.image = image;
this.buttonText = buttonText;
}
}
You need to add View.OnTouchListener to the parent view, in which your image is. Here parent view is your grid row.
It can be done via using setOnTouchListener(View.OnTouchListener). Below is code, you need to replace ViewHolder class with below code.
class ViewHolder implements View.OnTouchListener {
ImageView buttonImage;
TextView buttonText;
public ViewHolder(View v) {
this.buttonImage = (ImageView) v.findViewById(R.id.imageViewButton);
this.buttonText = (TextView) v.findViewById(R.id.textViewButton);
v.setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEvent.ACTION_DOWN == event.getAction()) {
// Here you can put animation for your image view
// this.buttonImage is the target image view.
}
return true;
}
}
Related
I have dynamically populated ImageViews and Textviews.
Now I have small problem with implementing onClick method on ImageView. On some ImageView click it should switch to fragment and for some click onto activity.
here is my code - my main fragment:
public class MainFragment extends Fragment {
public static String[] gridViewStrings = {
"string1",
"string2",
"string3",
"string4",
"string5",
"string6"
};
public static int[] gridViewImages = {
R.drawable.delivery,
R.drawable.shipping_logs,
R.drawable.meassurement,
R.drawable.takeovers,
R.drawable.settings,
R.drawable.download_data
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_fragment, parent, false);
gridView = (GridView) view.findViewById(R.id.grid);
gridView.setAdapter(new CustomAndroidGridViewAdapter(getActivity(), gridViewStrings, gridViewImages));
imageView = (ImageView) view.findViewById(R.id.gridview_image);
}
my custom gridview adapter:
public class CustomAndroidGridViewAdapter extends BaseAdapter {
private Context mContext;
private final String[] string;
private final int[] Imageid;
public CustomAndroidGridViewAdapter(Context c,String[] string,int[] Imageid ) {
mContext = c;
this.Imageid = Imageid;
this.string = string;
}
#Override
public int getCount() {
return string.length;
}
#Override
public Object getItem(int p) {
return null;
}
#Override
public long getItemId(int p) {
return 0;
}
#Override
public View getView(final int p, final View convertView, ViewGroup parent) {
View grid;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.grid, null);
TextView textView = (TextView) grid.findViewById(R.id.gridview_text);
ImageView imageView = (ImageView)grid.findViewById(R.id.gridview_image);
textView.setText(string[p]);
imageView.setImageResource(Imageid[p]);
} else {
grid = (View) convertView;
}
return grid;
}
}
QUESTION: How to implement onClick() on ImageView and switch to fragment and activity?
public DlgOutletListAdapter(Context context, List<WrapperOutlet> wrapperOutletList, View.OnClickListener listener) {
this.context = context;
this.wrapperOutletList = wrapperOutletList;
this.listener = listener; //---> pass in listener....
}
#Override
public int getCount() {
return wrapperOutletList.size();
}
#Override
public Object getItem(int position) {
return wrapperOutletList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_dlg_outlet_list, parent, false);
viewHolder = new ViewHolder(convertView);
viewHolder.ll_dlg_outlet_list_container.setOnClickListener(listener);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (!wrapperOutletList.isEmpty()) {
WrapperOutlet wrapperOutlet = wrapperOutletList.get(position);
Outlet outlet = wrapperOutlet.getOutlet();
if (outlet != null) {
if (TextUtils.isEmpty(outlet.getTel())){
viewHolder.ivCall.setImageResource(R.drawable.icon_call2);
viewHolder.tvCall.setTextColor(context.getResources().getColorStateList(R.color.medium_gray));
viewHolder.ll_dlg_outlet_list_dialer.setOnClickListener(null);
} else {
viewHolder.ivCall.setImageResource(R.drawable.icon_call);
viewHolder.tvCall.setTextColor(context.getResources().getColorStateList(R.color.fresh_teal));
viewHolder.ll_dlg_outlet_list_dialer.setOnClickListener(listener);
}
}
}
return convertView;
}
Pass in listener. Give you an example above. code below is where you call the adapter in fragment. My fragment implements View.OnClickListener
lv_dlg_outlet_list.setAdapter(new DlgOutletListAdapter(activity, wrapperOutletList, this));
Interface Callback:
public interface LaunchFragmentWithImage{
void launchFragmentWithImage(int imageID);
}
Give the adapter a reference of this class below so it can call the method. Wouldn't recommend giving the adapter itself a reference to the class because its not the adapters responsibility to know who recieves the image, thus violating the Single responsibility principle of OOD, but for the sake of learning it's okay.
public class ClassToLaunchNewFragment extends AppCompatActivity implements
LaunchFragmentWithImage{
#Override //Method from interface we've defined.
public void launchFragmentWithImage(int imageID){
FragmentToLaunch fragmentToLaunch = FragmentToLaunch.newInstance();
Bundle imageData = new Bundle();
imageData.putInt(imageID, "key");
fragmentToLaunch.setArguments(imageData);
getSupportFragmentManager().beginTransaction() //Call replace not add
.replace(containerID, fragmentToLaunch)
.commit();
}
}
In AdapterClass
imageViewVar.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
fragmentToLaunchInstanceThatWasPassedIn.launchFragmentWithImage(theImageResource);
}
});
grid = new View(mContext);
grid = inflater.inflate(R.layout.grid, null);
why are you pointing the grid variable to two separate View objects?
if (convertView == null) {
grid = inflater.inflate(R.layout.grid, null);
TextView textView = (TextView) grid.findViewById(R.id.gridview_text);
ImageView imageView = (ImageView)grid.findViewById(R.id.gridview_image);
textView.setText(string[p]);
imageView.setImageResource(Imageid[p]);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(choosedPosition){
case 0:do something;break;
case 1:do something;break;
...
}
}
});
}
It's just an example and can't running.
I have got a simple navigation drawer with a header (see picture).
What I want to do now is whenever the header (listview-item with position 0) is clicked to either change the down-arrow-icon (bottom right corner of header) to an up-arrow-icon or to rotate it so the arrow points up. How can i achieve this with my adapter?
My List-Adapter:
public class MyAdapter extends BaseAdapter {
private String[] _navTitles;
private int[] _navIcons;
private String _nameHeader;
private int _profileHeader;
private String _emailHeader;
public int _arrowHeader;
public MyAdapter(String[] navTitles, int[] navIcons, String nameHeader, String emailHeader, int profileHeader, int arrowHeader) {
_navTitles = navTitles;
_navIcons = navIcons;
_nameHeader = nameHeader;
_emailHeader = emailHeader;
_profileHeader = profileHeader;
_arrowHeader = arrowHeader;
}
#Override
public int getCount() {
return _navTitles.length;
}
#Override
public Object getItem(int position) {
return _navTitles[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder viewHolder = null;
if (view == null) {
if (position == 0) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);
viewHolder = new ViewHolder();
viewHolder.profileView = (CircleImageView) view.findViewById(R.id.circleView);
viewHolder.nameView = (TextView) view.findViewById(R.id.name);
viewHolder.emailView = (TextView) view.findViewById(R.id.email);
viewHolder.arrowView = (ImageView) view.findViewById(R.id.arrow);
viewHolder.holderID = 0;
view.setTag(viewHolder);
} else {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
viewHolder = new ViewHolder();
viewHolder.textView = (TextView) view.findViewById(R.id.rowText);
viewHolder.imageView = (ImageView) view.findViewById(R.id.rowIcon);
viewHolder.holderID = 1;
view.setTag(viewHolder);
}
} else {
viewHolder = (ViewHolder) view.getTag();
}
if (_navTitles.length > position && position != 0) {
viewHolder.textView.setText(_navTitles[position]);
viewHolder.textView.setTag(_navTitles[position]);
viewHolder.imageView.setImageResource(_navIcons[position]);
viewHolder.imageView.setTag(_navIcons[position]);
}
if (position == 0) {
viewHolder.profileView.setImageResource(_profileHeader);
viewHolder.nameView.setText(_nameHeader);
viewHolder.emailView.setText(_emailHeader);
viewHolder.arrowView.setImageResource(_arrowHeader);
}
return view;
}
public static class ViewHolder {
int holderID;
TextView textView;
ImageView imageView;
CircleImageView profileView;
TextView nameView;
TextView emailView;
ImageView arrowView;
}
}
Thanks for any help!
I solved it by myself. If anybody needs it:
final ViewHolder finalViewHolder = viewHolder;
viewHolder.arrowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (finalViewHolder.arrowView.getTag().equals("down")) {
finalViewHolder.arrowView.setImageResource(R.drawable.ic_arrow_drop_up_white_48dp);
finalViewHolder.arrowView.setTag("up");
} else if (finalViewHolder.arrowView.getTag().equals("up")) {
finalViewHolder.arrowView.setImageResource(R.drawable.ic_arrow_drop_down_white_48dp);
finalViewHolder.arrowView.setTag("down");
}
}
});
I load images via Picasso Library in my custom adapter and then show it in my ListFragment. When I am trying to scroll, some of the images changes order (I think it is something wrong with reusing cells).
What is the best place to download images asynchronously? I do it in my custom adapter with viewholder.
public class PostsAdapter extends BaseAdapter {
private static final String TAG = "tag.example.tag";
private static final String URL_PREFIX = "http://someapi.com/v1/api/";
private Context mContext;
private ArrayList<Post> mData;
private static LayoutInflater inflater = null;
public PostsAdapter(Context context, ArrayList<Post> data) {
mContext = context;
mData = data;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
}
#Override
public boolean isEnabled(int position) {
return true;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
ViewHolder holder = null;
if(view == null)
v = inflater.inflate(R.layout.post_listviewrow, null);
holder = new ViewHolder();
holder.imageView = (ImageView) v.findViewById(R.id.imageView);
Post post = (Post) mData.get(i);
// Download image with Picasso
holder.imageView.setTag(post.getPictureUrl());
Picasso.with(mContext).load(URL_PREFIX + post.getPictureUrl()).into(holder.imageView);
return v;
}
static class ViewHolder {
TextView titleTextView;
ImageView imageView;
}
}
SOLUTION:
Changed getView method to something like this
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder holder;
if(view == null) {
view = inflater.inflate(R.layout.post_listviewrow, null);
holder = new ViewHolder();
holder.imageView = (ImageView) view.findViewById(R.id.imageView);
holder.titleTextView = (TextView) view.findViewById(R.id.textview);
holder.progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Get position
Post post = (Post) mData.get(i);
holder.titleTextView.setText(post.getTitle());
Picasso picasso = Picasso.with(mContext);
picasso.setIndicatorsEnabled(true);
holder.progressBar.setVisibility(View.VISIBLE);
picasso.load(URL_PREFIX + post.getPictureUrl())
.placeholder(R.drawable.placeholder)
.fit()
.centerCrop()
.into(holder.imageView, new Callback() {
#Override
public void onSuccess() {
holder.progressBar.setVisibility(View.GONE);
}
#Override
public void onError() {}
});
return view;
}
static class ViewHolder {
TextView titleTextView;
ImageView imageView;
ProgressBar progressBar;
}
Anyway, Do you think the adapter is the right place to put download tasks?
Im using a listView that have 2 layouts for the rows on one row the
setOnItemClickListener
but on the other row it doesnt recognize the taps,
public void initItemTable()
{
listViewItem = (ListView) getView().findViewById(R.id.listViewItem);
listViewItem.setAdapter(new PhoneItemAdapter(new ItemPhoneDataSource().getItems()));
listViewItem.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
Log.d("mensa", "item index :"+arg2);
}
});
}
//
private class PhoneItemAdapter extends BaseAdapter {
final List<RowPhone> rows;//row
//data source, style
PhoneItemAdapter(List<ItemPhone> animals) {
rows = new ArrayList<RowPhone>();//member variable
//choose cell! iterator
for (ItemPhone item : animals) {
if (item.getType().equals("item")) {
rows.add(new RowItemPhone(LayoutInflater.from(getActivity()), item));
} else {
rows.add(new RowFolderPhone(LayoutInflater.from(getActivity()), item)); //imageRow!
}
}
}
//delegate
#Override
public int getViewTypeCount() {
return RowTypePhone.values().length;
}
#Override
public int getItemViewType(int position) {
//con cast
return ((RowPhone) rows.get(position)).getViewType();
}
public int getCount() {
return rows.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
//cambiado con cast!
return ((RowPhone) rows.get(position)).getView(convertView);
}
}
So the tap is detected when "item.getType()" is folder but not in item,
. Shall I include the code for RowItemPhone.java and RowFolderPhone.java?
so how to fix this tap problem?
thanks!
edit 1. RowPhone.java
public interface RowPhone {
public View getView(View convertView);
public int getViewType();
}
edit 2. RowFolder.java .. the one that have the tap detecting fine:
public class RowItemPhone implements RowPhone{
private final ItemPhone item;
private final LayoutInflater inflater;
public RowItemPhone(LayoutInflater inflater, ItemPhone animal) {
this.item = animal;
this.inflater = inflater;
}
//text doble
public View getView(View convertView) {
ViewHolder holder;
View view = null;
if (convertView == null) {
//ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_item_phone, null);
ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_item_phone, (ViewGroup) view, false);
holder = new ViewHolder(
(ImageView)viewGroup.findViewById(R.id.image_item),
(TextView)viewGroup.findViewById(R.id.title),
(TextView)viewGroup.findViewById(R.id.description));
viewGroup.setTag(holder); //pa q y como usa tag!
view = viewGroup;
} else {
view = convertView;
holder = (ViewHolder)convertView.getTag();
}
//setup
holder.imageView.setImageResource(item.getImageId());
holder.descriptionView.setText(item.getDescription());
holder.titleView.setText(item.getName());
return view;
}
public int getViewType() {
return RowTypePhone.DESCRIPTION_ROW.ordinal();
}
private static class ViewHolder {
final ImageView imageView;
final TextView titleView;
final TextView descriptionView;
private ViewHolder(ImageView imageView, TextView titleView, TextView descriptionView) {
this.imageView = imageView;
this.titleView = titleView;
this.descriptionView = descriptionView;
}
}
}
And here the RowFolderPhone.java ... showing fine, but not detecting taps:
public class RowFolderPhone implements RowPhone {
private final ItemPhone item;
private final LayoutInflater inflater;
public RowFolderPhone(LayoutInflater inflater, ItemPhone animal) {
this.item = animal;
this.inflater = inflater;
}
public View getView(View convertView) {
ViewHolder holder;
View view = null;
//we have a don't have a converView so we'll have to create a new one
if (convertView == null) {
// ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_folder_phone, null);
ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_folder_phone, (ViewGroup) view, false);
//use the view holder pattern to save of already looked up subview
holder = new ViewHolder((ImageView)viewGroup.findViewById(R.id.image),
(TextView)viewGroup.findViewById(R.id.title));
viewGroup.setTag(holder);
view = viewGroup;
} else {
//get the holder back out
holder = (ViewHolder)convertView.getTag();
view = convertView;
}
//actually setup the view
holder.imageView.setImageResource(item.getImageId());
holder.titleView.setText(item.getName());
return view;
}
public int getViewType() {
return RowTypePhone.IMAGE_ROW.ordinal();
}
private static class ViewHolder {
final ImageView imageView;
final TextView titleView;
private ViewHolder(ImageView imageView, TextView titleView) {
this.imageView = imageView;
this.titleView = titleView;
}
}
}
There are something wrong with your getItem method on PhoneItemAdapter. getItem method should return list item not position. So you should replace your code to
public RowPhone getItem(int position) {
return rows.get(position);
}
the problem was solved by setting descendantFocusability
in : row_item_phone.xml
<RelativeLayout ...
android:descendantFocusability="blocksDescendants"
I'm developing an Android Application and I have a custom adapter for my ListView. I want to use a Pull to refresh library, such as this one. This works fine with an ArrayAdapter, but not with a custom adapter.
How can I get my pull to refresh working with a custom adapter?
Here my adapter code:
public class AdvertListAdapter extends BaseAdapter {
private AdvertListActivity activity;
private int currentFirstVisibleItem=0;
private int currentLastVisibleItem=8;
public AdvertListAdapter(AdvertListActivity activity) {
this.activity = activity;
}
public void setFirstVisibleItem(int currentFirstVisibleItem) {
this.currentFirstVisibleItem=currentFirstVisibleItem;
}
public void setLastVisibleItem(int currentLastVisibleItem) {
this.currentLastVisibleItem=currentLastVisibleItem;
}
#Override
public int getCount() {
return activity.getAdvertList().size();
}
#Override
public Advert getItem(int pos) {
return activity.getAdvertList().get(pos);
}
#Override
public long getItemId(int pos) {
return activity.getAdvertList().get(pos).getId();
}
private class ViewHolder {
public ImageView image;
public TextView title;
public TextView price;
public TextView size;
public TextView city;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView == null) {
view = new ViewHolder();
convertView = inflator.inflate(R.layout.listview_advertlist, null);
view.image = (ImageView) convertView.findViewById(R.id.advertImage);
view.title = (TextView) convertView.findViewById(R.id.advertTitleText);
view.price = (TextView) convertView.findViewById(R.id.advertPriceText);
view.size = (TextView) convertView.findViewById(R.id.advertSizeText);
view.city = (TextView) convertView.findViewById(R.id.advertCityText);
convertView.setTag(view);
}else {
view = (ViewHolder) convertView.getTag();
}
Advert advert = activity.getAdvertList().get(position);
view.title.setText(advert.getTitle());
view.price.setText(String.valueOf(advert.getPrice()+"€"));
view.size.setText("Taille: "+advert.getSize());
view.city.setText(advert.getCity());
if(position <= currentFirstVisibleItem || position >= currentLastVisibleItem) {
view.image.setImageResource(R.drawable.defaultadvertimage);
ServiceHelper.loadAsyncImage(view.image, activity.getApplicationContext(), String.valueOf(advert.getId()+"-mini"), "advert");
}
return convertView;
}
}
Here my activity code:
list = (PullToRefreshListView) findViewById(R.id.advertList);
advertList = getAdvertList();
((PullToRefreshListView) list).setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
// Do work to refresh the list here.
new GetDataTask().execute();
}
});
list.setAdapter(adapter);