Hello and thanks for your help!
Upon clicking the button, the alertdialog should open up with a gridview inside.
This is my code:
loginWith.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle(getResources().getString(R.string.loginWith));
final AlertDialog dialog = builder.create();
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.dialog_loginwith, (ViewGroup) findViewById(R.id.layout_loginwith));
builder.setView(layout);
GridView gridView = (GridView) layout.findViewById(R.id.gvLoginwith);
gridView.setAdapter(new LoginWithAlertDialogImageAdapter(context));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
loginWithFacebook();
break;
case 1:
loginWithGoogle();
break;
case 2:
loginWithLinkedIn();
break;
case 3:
loginWithTwitter();
break;
}
dialog.dismiss();
}
});
dialog.show();
}
});
But it ends up leaving the NullPointerException at gridView.setAdapter() part above and the context.getResources().getString() methods in the following class.
public class LoginWithAlertDialogImageAdapter extends BaseAdapter {
private Context context;
private LayoutInflater mLayoutInflater;
public LoginWithAlertDialogImageAdapter(Context context) {
this.context = context;
mLayoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.categorycontent_log_in_with, null);
convertView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.loginwith_title);
holder.icon = (ImageView) convertView.findViewById(R.id.loginwith_icon);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setAdjustViewBounds(true);
holder.icon.setScaleType(ImageView.ScaleType.FIT_XY);
holder.icon.setPadding(8, 8, 8, 8);
holder.title.setText(items[position]);
holder.icon.setImageResource(icons[position]);
return convertView;
}
class ViewHolder {
TextView title;
ImageView icon;
}
private Integer[] icons = {
R.drawable.ic_facebook,
R.drawable.ic_google,
R.drawable.ic_linkedin,
R.drawable.ic_twitter
};
private String[] items = {
context.getResources().getString(R.string.facebook),
context.getResources().getString(R.string.google),
context.getResources().getString(R.string.linkedin),
context.getResources().getString(R.string.twitter)
};
}
How should this be overcome?
Added I corrected the adapter code following the suggestion as follows.
public class LoginWithAlertDialogImageAdapter extends BaseAdapter {
private Context context;
private LayoutInflater mLayoutInflater;
private String items[];
public LoginWithAlertDialogImageAdapter(Context context) {
this.context = context;
mLayoutInflater = LayoutInflater.from(context);
items = new String[] {
context.getResources().getString(R.string.facebook),
context.getResources().getString(R.string.google),
context.getResources().getString(R.string.linkedin),
context.getResources().getString(R.string.twitter)
};
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.categorycontent_log_in_with, null);
convertView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.loginwith_title);
holder.icon = (ImageView) convertView.findViewById(R.id.loginwith_icon);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setAdjustViewBounds(true);
holder.icon.setScaleType(ImageView.ScaleType.FIT_XY);
holder.icon.setPadding(8, 8, 8, 8);
holder.title.setText(items[position]);
holder.icon.setImageResource(icons[position]);
return convertView;
}
class ViewHolder {
TextView title;
ImageView icon;
}
private Integer[] icons = {
R.drawable.ic_facebook,
R.drawable.ic_google,
R.drawable.ic_linkedin,
R.drawable.ic_twitter
};
}
Now the NullPointerException is not thrown anymore, but the thing is the icons and the icon titles and the GridView itself are not shown, but only the title of the AlertDialog is shown. Do you figure out the next issue?
Here:
context.getResources().getString(R.string.facebook)
context is null .
Why?
items Array is declared and initialized as a class level variable, during adding items in items Array, using context for accessing getResources method which is null because context is initialized inside constructor of LoginWithAlertDialogImageAdapter class.
Means context is accessed before executing constructor of LoginWithAlertDialogImageAdapter class.
So, to fix this issue declare items Array as class level variable but add item in it after initializing context :
private String[] items;
public LoginWithAlertDialogImageAdapter(Context context) {
this.context = context;
...
items = {
context.getResources().getString(R.string.facebook),
...
};
}
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 am having a listview in my App. Each row has an button. I'm hiding the button for some rows with setVisibility. But the buttons visibility changes after scrolling the list. How can i stop this change ?
I already saw a question with the checkbox with Listview. But i don't know how to implement it for the buttons. So please guide me!
ADAPTER
public class published_adapter extends BaseAdapter {
Context con;
ArrayList<HashMap<String, String>> class_list;
LayoutInflater inflater;
public class ViewHolder
{
TextView title,description,class_section,date;
ImageButton download;
Button viewasgn;
}
public published_adapter(Context co, ArrayList<HashMap<String, String>> list1) {
class_list = list1;
con = co;
inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return class_list.size();
}
#Override
public Object getItem(int arg0) {
return class_list.get(arg0).get("class_name");
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(final int arg0, View arg1, ViewGroup arg2) {
View row = arg1;
ViewHolder holder = new ViewHolder();
if(row == null)
{
row = inflater.inflate(
R.layout.assignment_adapter_layout, arg2, false);
// initialize the elements
holder.download = (ImageButton) row.findViewById(R.id.download);
holder.title = (TextView) row.findViewById(R.id.title);
holder.description = (TextView) row.findViewById(R.id.description);
holder.class_section = (TextView) row.findViewById(R.id.class_section);
holder.date = (TextView) row.findViewById(R.id.date);
holder.viewasgn = (Button) row.findViewById(R.id.attend);
row.setTag(holder);
}
else
{
holder = (ViewHolder)row.getTag();
}
String type = class_list.get(arg0).get("ASSIGNMENT_TYPE");
if (class_list.get(arg0).get("TOTAL_SUBMISSION").equals("0")) {
Log.e("TITLE", class_list.get(arg0).get("TOTAL_SUBMISSION"));
}
else{
Log.e("TITLE", class_list.get(arg0).get("TOTAL_SUBMISSION"));
holder.viewasgn.setVisibility(View.VISIBLE);
holder.viewasgn.setText("VIEW");
}
return row;
}
}
Update your code like this
if (class_list.get(arg0).get("TOTAL_SUBMISSION").equals("0")) {
Log.e("TITLE", class_list.get(arg0).get("TOTAL_SUBMISSION"));
holder.viewasgn.setVisibility(View.INVISIBLE);
holder.viewasgn.setText("");
}
else{
Log.e("TITLE", class_list.get(arg0).get("TOTAL_SUBMISSION"));
holder.viewasgn.setVisibility(View.VISIBLE);
holder.viewasgn.setText("VIEW");
}
Either add the setVisibility(View.INVISIBLE) like #Solhail suggested or hide those buttons by default in your assignment_adapter_layout.xml by adding android:visibility="invisible" in your Button's properties, and don't change a thing in your current adapter code.
In your case Views will be recreated when listView is scroll.
To prevent this, you should not use ViewHolder.
You need to user Adapter like this:
(Only if you have not a lot elements)
public class SampleAdapter extends BaseAdapter {
private ArrayList<String> arrayList;
private Activity activity;
public SampleAdapter(ArrayList<String> arrayList, Activity activity) {
this.arrayList = arrayList;
this.activity = activity;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = activity.getLayoutInflater();
View view = layoutInflater.inflate(R.layout.sample_element, parent, false);
TextView textViewTitle = (TextView) view.findViewById(R.id.text_view_title);
textViewTitle.setText(arrayList.get(position));
return view;
} }
Is it possible to change row view when I'm clicking on it? For example I have listView with rows where some short information shown, and when after clicking on row detailed view will show instead of old row.
I tried to use addView in my listView, but "listview addView(View, int) is not supported in AdapterView" error appeared.
try something like that:
public class MyAdapter extends BaseAdapter {
private Context mContext;
private List<UserPojo> mList;
public MyAdapter(Context context, List<UserPojo> users) {
this.mContext = context;
this.mList = users;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public UserPojo getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final UserPojo user = mList.get(position);
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_ad, null);
holder = new ViewHolder();
holder.pic = (CircleImageView) convertView.findViewById(R.id.profile_imageView);
holder.name = (TextView) convertView.findViewById(R.id.name_textView);
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
}
if (user.isClicked) {
holder.pic.setVisibility(View.VISIBLE);
holder.name.setVisibility(View.GONE);
} else {
holder.pic.setVisibility(View.GONE);
holder.name.setVisibility(View.VISIBLE);
}
holder.name.setText("text");
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
user.setClicked(true);
notifyDataSetChanged();
}
});
return convertView;
}
private static class ViewHolder {
CircleImageView pic;
TextView name;
}
}
I am working on BaseAdapter. I wrote some code which can show images and text in listview with baseAdapter. Now i want to change images and text background by position.
this is a my baseAdapter code
public class SlideMenuAdapter extends BaseAdapter {
private Context mContext;
private final String[] menu_items_id;
private final int[] Imageid;
TextView textView;
ImageView imageView;
private static LayoutInflater inflater = null;
public SlideMenuAdapter(Context context, String[] names, int[] Imageid)
{
mContext = context;
this.Imageid = Imageid;
this.menu_items_id = names;
inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return Imageid.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#SuppressLint("ViewHolder")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View grid;
grid = new View(mContext);
grid = inflater.inflate(R.layout.azercell_slidemenu_adaper, null);
textView = (TextView) grid.findViewById(R.id.desc);
imageView = (ImageView) grid.findViewById(R.id.photo);
textView.setText(menu_items_id[position]);
imageView.setImageResource(Imageid[position]);
return grid;
}
}
and this is a my listview listener code
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
TextView textView1 = (TextView) parent.findViewById(R.id.desc);
ImageView imageView=(ImageView)parent.findViewById(R.id.photo);
switch (position) {
case 0:
textView1.setTextColor(Color.parseColor("#8f332a"));
imageView.setImageResource(menu_imagesover[position]);
break;
case 1:
textView1.setTextColor(Color.parseColor("#ffffff"));
imageView.setImageResource(menu_imagesover[position]);
break;
default:
break;
}
}
});
int[] menu_imagesover = { R.drawable.schedule_ove, R.drawable.about_over,
R.drawable.booking_over };
when I click in listview I can only change first item 's images and text background. how I can write code to can change each item by position?
Try to call invalidate method to refresh your listview :
switch (position) {
case 0:
textView1.setTextColor(Color.parseColor("#8f332a"));
imageView.setImageResource(menu_imagesover[position]);
break;
case 1:
textView1.setTextColor(Color.parseColor("#ffffff"));
imageView.setImageResource(menu_imagesover[position]);
break;
default:
break;
}
invalidate(); //add here
Or if its not working, try to call invalidateViews instead of invalidate.
And i think theres something fishy about switch (position), doesnt it means your code will only work if the 1st and 2nd row is clicked?
Take ArrayList with Hashmap which hold all info for list item :
ArrayList<HashMap<String,Object>> listData = new ArrayList<HashMap<String, Object>>();
HashMap<String,Object> row1 = new HashMap<String, Object>();
row1.put("name","item1");
row1.put("normalImage",R.drawable.ic_launcher);
row1.put("selectedImage",R.drawable.ic_launcher);
row1.put("normalTextColor","#000000");
row1.put("selectedTextColor","#ff0000");
row1.put("isClick",false);
listData.add(row1);
SlideMenuAdapter adapter = new SlideMenuAdapter(context,listData);
Change state of particular list item click
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
if((Boolean)listData.get(position).get("isClick")){
listData.get(position).put("isClick",false);
}else{
listData.get(position).put("isClick",true);
}
adapter.notifyDataSetChanged();
}
});
Check item click state in getView() adapter :
public class SlideMenuAdapter extends BaseAdapter {
private Context context;
private ArrayList<HashMap<String,Object>> data;
public SlideMenuAdapter(Context context, ArrayList<HashMap<String,Object>> data)
{
this.context = context;
this.data = data;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.azercell_slidemenu_adaper, null);
holder.textView = (TextView) convertView.findViewById(R.id.desc);
holder.imageView = (ImageView) convertView.findViewById(R.id.photo);
convertView.setTag(holder);
}else{
holder =(ViewHolder) convertView.getTag();
}
holder.textView.setText(data.get(position).get("name").toString());
if((Boolean)data.get(position).get("isClick")){
holder.textView.setTextColor(Color.parseColor(data.get(position).get("selectedTextColor").toString()));
holder.imageView.setImageResource((Integer)data.get(position).get("selectedImage"));
}else{
holder.textView.setTextColor(Color.parseColor(data.get(position).get("normalTextColor").toString()));
holder.imageView.setImageResource((Integer)data.get(position).get("normalImage"));
}
return convertView;
}
class ViewHolder{
TextView textView;
ImageView imageView;
}
}
i have fragment in which i have a listview , i was trying to show some data in the list . it is silly but its not working i have no idea what is wrong with it.
in my fragmnet in oncreateview im doing this
mContactsHomeAdapter = new ContactsHomeAdapter(getActivity());
mListView.setAdapter(mContactsHomeAdapter);
mContactsHomeAdapter.notifyDataSetChanged();
this is my adapter code
public class ContactsHomeAdapter extends BaseAdapter {
ExecutorService executorService;
private Context mContext;
LayoutInflater mInflater;
public ContactsHomeAdapter(Context pContext) {
mContext = pContext;
//executorService=Executors.newFixedThreadPool(10);
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return 100;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = mInflater.inflate(R.layout.contacts_adapter_item, null);
}
CheckBox lCheckbox = (CheckBox) convertView.findViewById(R.id.check_box);
TextView lContactTitle = (TextView) convertView.findViewById(R.id.contact_title);
TextView lContactEmail = (TextView) convertView.findViewById(R.id.contact_email);
ImageView lContactPhoto = (ImageView) convertView.findViewById(R.id.contact_photo);
TextView lContactNumber = (TextView) convertView.findViewById(R.id.contact_phonenumber);
lContactTitle.setText("hello");
// QueueItem lItem = new QueueItem() ;
// lItem.mId = ""+position;
// lItem.mName = lContactTitle;
// lItem.mNumber = lContactNumber;
// lItem.mEmail = lContactEmail;
// executorService.submit(new QueueRunner(lItem));
return convertView;
}
}