I have a spinner and I want to show/hide something when the user exits the spinner without doing any thing. for example, when the user touches an area outside the spinner.
p.s. the onTouchEvent for the container layout (LinearLayout in my case) is also not called.
here is my implementation for the custom spineer:
public SpinnerHintAdapter(Activity context, int resourceId, int textViewId, List<SpinnerItem> list, Spinner parent){
super(context,resourceId,textViewId, list);
flater = context.getLayoutInflater();
this.items = list;
this.gender = parent;
}
#Override
public int getCount() {
return items.size();
}
#Nullable
#Override
public SpinnerItem getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
SpinnerItem spinnerItem = getItem(position);
View rowView = flater.inflate(R.layout.gender_item ,null,true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.main_text);
txtTitle.setText(spinnerItem.getName());
txtTitle.setTextColor(txtTitle.getResources().getColor(R.color.color_white));
Log.i(Tags.byEmail, "VVVVVVVVVVVVv");;
gender.setVisibility(View.VISIBLE);
return rowView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
firstTime = false;
SpinnerItem rowItem = getItem(position);
View rowView = flater.inflate(R.layout.gender_drop_down_item ,null,true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.drop_down_text);
txtTitle.setText(rowItem.getName());
if(!isEnabled(position)){
txtTitle.setBackground(txtTitle.getResources().getDrawable(R.drawable.normal_rounded_text_field));
txtTitle.setTextColor(Color.parseColor("#777777"));
}
parent.setBackground(parent.getResources().getDrawable(R.drawable.normal_rounded_text_field));
txtTitle.setEnabled(isEnabled(position));
gender.setVisibility(View.INVISIBLE);
Log.i(Tags.byEmail, "DDDDDDDDDDDDDDDDDD");
return rowView;
}
#Override
public boolean isEnabled(int position) {
if(position == 0)
return false;
return super.isEnabled(position);
}
}
when the user exits without selecting an item the getView function is not called and hence the gender (is the spinner object itself) will not be visible.
I tried OnItemSelected and OnNothingSelected are also not called.
event OnTouch events are not called.
The following Events are not called when the user exits:
1- OnItemSlected
2- OnNothingSelected
3- OnFocusChanged.
4- OnTouch
I think that's event will work for you as magic, no?
public class CustomSpinner extends Spinner {
... Constructors ...
#Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
Log.d(CustomSpinner.class.getSimpleName(), "onWindowFocusChanged: " + hasWindowFocus);
if (hasWindowFocus) {
// User click out of window
} else {
// User click in spinner window
}
}
}
With a Spinner you set an AdapterView.OnItemSelectedListener which implements two methods; onItemSelected and onNothingSelected.
Like this:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// This is called when the user selects an item in the Spinner
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// This is called when the user closes the spinner selecting nothing
}
});
Related
I'm working on AndroidStudio with Java.
I have many imageviews inside gridview.
and I'm trying to apply click event which affects multiple imageviews at the same time
what I want to do is :
when one imageview is clicked another imageview, which is not been clicked to change its image.
for example, there is two imageview A and B in same gridview. if I click A imageview, both A and B imageview set to different imagesources.
what I can do is change only clicked imageview.
I want to know how to access the unclicked items in gridview.
I made onclick listener inside adapter.
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.ingrid,parent,false);
ImageView blackorwhite = convertView.findViewById(R.id.blackOrWhite);
Integer val = mData.get(position);
blackorwhite.setImageResource(blockColor.get(val));
blackorwhite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
blackorwhite.setImageResource(R.color.white);
}
});
you can make an interface callback to know which item gets clicked for example this is ur interface
interface OnClickListener {
void onClick(int position)
}
and pass this interface to ur Adapter,
and in the getView method whenever a view get clicked u can call the onClick method of the interface
this is example code
interface OnClickListener {
void onClick(int position);
}
public class GridViewAdapter extends BaseAdapter {
private List<String> list;
private OnClickListener listener;
private Context context;
public GridViewAdapter(Context context,List<String> list,OnClickListener listener){
this.listener = listener;
this.context = context;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(ur layout);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onClick(position);
}
});
return view;
}
}
To initiate The adapter, u can use this code,
GridViewAdapter adapter = new GridViewAdapter(context, imageList, new OnClickListener() {
#Override
public void onClick(int position) {
// this method called every time an view get clicked
// and u can change the DataSet which now is imageList
// imageList.set(position,"something new ");
// after the change of DataSet u should cal the notifyDataSetChanged
adapter.notifyDataSetChanged();
}
});
I'm getting a variable data sent from activity to my adapter by using
sendData method, but every time when I try to access it in my getView method it resets to 0, please help. I've tried to debug code to check if the data from an activity is passing and it looks ok. I also created a getNumb method but still, the variable resets to 0. Here is my adapter code:
public class WorkoutListAdapterTwo extends BaseAdapter {
private int y;
public WorkoutListAdapterTwo() {
}
public int sendData(int x){
this.y = x;
return y;
}
public int getNumb(){
return this.y;
}
private static LayoutInflater mLayoutInflater = null;
public WorkoutListAdapterTwo(Activity ctx) {
this.mLayoutInflater = ctx.getLayoutInflater();
}
#Override
public int getCount() {
return WorkoutContentTwo.WORKOUTSTWO.size();
}
#Override
public Object getItem(int position) {
return WorkoutContentTwo.WORKOUTSTWO.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
int j = getNumb();
WorkoutTwo workout = (WorkoutTwo) getItem(j);
String [] arrOfStrings = workout.name.split(",");
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.adapter_workout_row, parent, false);
holder = new ViewHolder();
holder.id = (TextView) convertView.findViewById(R.id.workout_id);
holder.name = (TextView) convertView.findViewById(R.id.workout_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Set the content for the ListView row
//holder.id.setText(workout.id);
//holder.name.setText(arrOfStrings[i]);
holder.id.setText(Integer.toString(position+1));
holder.name.setText(workout.ArrList[position]);
// Set the color for the ListView row
holder.id.setBackgroundColor(workout.dark);
holder.name.setBackgroundColor(workout.light);
return convertView;
}
Here I'm adding the code where I'm calling my method:
public void onItemSelected(int position) {
// Start the detail activity for the selected workout ID.
Intent detailIntent = new Intent(this, WorkoutDetailActivityTwo.class);
detailIntent.putExtra(WorkoutDetailFragmentTwo.ARG_WORKOUT_POS, position);
WorkoutListAdapterTwo newAdd = new WorkoutListAdapterTwo();
newAdd.sendData(position);
newAdd.notifyDataSetChanged();
startActivity(detailIntent);
}
Are you notifying your adapter to update views after updating the value? If your sendData() is not called until after the adapter has done it's first draw, you will need to call notifyDataSetChanged() so that the adapter knows there are new values that should be used to update your views.
You have to make a interface or you can a use notifyDataSetChanged depends on the use if you are doing search operation then use the notifyDataSetChanged method but if you want to send some data then
Fragment or activity
public class ExampleFragment extends Fragment implements MyAdapter.SuccessResponse{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.my_layout, container, false);
MyAdapter myAdapter = new MyAdapter(getActivity(), 0);
myAdapter.successResponse = this;
return contentView;
}
#Override
public void onSuccess() {
}
}
The adapter code
class MyAdapter extends ArrayAdapter{
SuccessResponse successResponse;
public MyAdapter(Context context, int resource) {
super(context, resource);
}
public interface SuccessResponse{
void onSuccess();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//ur views
linearLayout.setOnClickListener(new View.OnClickListener{
#Override
public void onClick (View view){
if(successResponse!=null)
successResponse.onSuccess();
}
})
}
}
You can use any type of adapter i am use arrayadaper here.
I've got a ListView filled with multiple items per row. How do i set an OnCLickListener in getView() of the custon ArrayAdapter class for just one Item, not the whole row of the ListView?
#NonNull
#Override
public View getView(final int position, #Nullable final View convertView, #NonNull final ViewGroup parent) {
currentLayout = getItem(position);
myViewHolder= null;
view = convertView;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.rowlayout, parent, false);
myViewHolder= new ViewHolder(view);
view.setTag(myViewHolder);
}
myViewHolder= (ViewHolder) view.getTag();
myViewHolder.content.setText(currentLayout.getContent());
myViewHolder.number.setText("1");
return view;
}
Thank you for the answers.
To clarify first, view which you inflate is the row layout. In order to set the on click listener on a child item, simply find that item by id and then set the listener:
//It can be any type of view that supports on click listener
//Using TextView as an example
//Don't forget to assign an id to the child in xml
TextView childView = (TextView) view.findViewById(R.id.enter_child_id);
childView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Do something
}
});
To have a different listener for different rows, it is better to set the listener in the onBindViewHolder not getView. getView is simply used just to inflate the view and therefore will make all your listeners on all rows non-distinguishable. In that case you can extract view or child views directly from the viewholder
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
TextView childView = holder.childView;
childView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Do something
}
});
}
#NonNull
#Override
public View getView(final int position, #Nullable final View convertView, #NonNull final ViewGroup parent) {
currentLayout = getItem(position);
myViewHolder= null;
view = convertView;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.rowlayout, parent, false);
myViewHolder= new ViewHolder(view);
view.setTag(myViewHolder);
}
myViewHolder= (ViewHolder) view.getTag();
myViewHolder.content.setText(currentLayout.getContent());
myViewHolder.number.setText("1");
yourview.setonclickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
do your stuff here
}
});
return view;
}
The problem was, that I was using a LsitView instead of a RecyclerView. After fixing that issue and calling the onCLick in onBindViewHolder, everything went fine.
I'm trying to implement an Android app for sudoku game, and i created a customized adapter for that. i want make edit text for cells the user is allowed to modify, and textview for cell filled by the program, the number of ediTexts and textViews will be random. how do specify that in the adapter ?
This is my adapter :
public class SodukuAdapter extends BaseAdapter {
ArrayList<String> items;
static Activity mActivity;
private static LayoutInflater inflater = null;
public SodukuAdapter (Activity activity, ArrayList<String> tempTitle,) {
mActivity = activity;
items = tempTitle;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public final int getCount() {
return items.size();
}
#Override
public final Object getItem(int position) {
return items.get(position);
}
#Override
public final long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = null;
v = inflater.inflate(R.layout.item, null);
EditText et = (EditText) v.findViewById(R.id.et);
et.setText(items.get(position));
return v;
}
}
You can place both views in the same parent (e. g. parent is a RelativeLayout or a FrameLayout) so they are on top of each other. Than you simply hide one of them and show the other using setVisibility() in your getView() method of the adapter.
Of course you would need a datasource object which keeps track of whether a view should show the TextView or the EditText:
class SodokuItem {
public boolean isStatic;
public String text;
}
...
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = inflater.inflate(R.layout.item, null);
SodokuItem item = items.get(position);
EditText et = (EditText) v.findViewById(R.id.et);
TextView tv = (TextView) v.findViewById(R.id.tv);
if(item.isStatic){
et.setVisibility(GONE);
tv.setText(item.text);
}else{
tv.setVisibility(GONE);
et.setText(item.text);
}
return v;
}
I have referenced to a tutorial and I have created a custom list view in fragment, but I am unable to get the position or value of any item on item click of list view. I want to show a toast containing the position of the item. I don't know how to implement that.
CustomListAdapter.java
public class CustomListAdapter extends BaseAdapter{
private ArrayList<MyActivityAdapterItem> listData;
private Context context;
//private LayoutInflater layoutInflater;
public CustomListAdapter(Context context, ArrayList<MyActivityAdapterItem> listData) {
this.listData = listData;
this.context = context;
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
//ViewHolder holder;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_row_layout, null);
// holder = new ViewHolder();
//convertView.setTag(holder);
}
TextView headingView = (TextView) convertView.findViewById(R.id.title);
TextView placeView = (TextView) convertView.findViewById(R.id.place);
TextView reportedDateView = (TextView) convertView.findViewById(R.id.date);
headingView.setText(listData.get(position).getHeading());
placeView.setText("At, " + listData.get(position).getPlace());
reportedDateView.setText(listData.get(position).getDate());
return convertView;
}
}
FindPeopleFragment.java
public class FindPeopleFragment extends Fragment implements OnClickListener {
AlertDialog.Builder builder ;
ListView lv1;
ImageButton delall;
CharSequence options[] = new CharSequence[] {"Delete"};
ArrayList details;
CustomListAdapter ad1;
String msg="abc";
public FindPeopleFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_find_people, container, false);
delall=(ImageButton) rootView.findViewById(R.id.deleteall);
details = getListData();
lv1 = (ListView) rootView.findViewById(R.id.activitylist);
ad1=new CustomListAdapter(getActivity(), details);
lv1.setAdapter(ad1);
builder= new AlertDialog.Builder(getActivity());
delall.setOnClickListener(this);
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
//Toast.makeText(getActivity(), , Toast.LENGTH_LONG).show();
/*Bundle args = new Bundle();
args.putString(MyActivitiesFragment.MSG, msg);
MyActivitiesFragment f1=new MyActivitiesFragment();
f1.setArguments(args);
MainActivity.fm.beginTransaction().replace(R.id.frame_container,f1).commit();*/
}
});
return rootView;
}
The position of the clicked item in a ListView can be retrived easily on the onItemClick method as you can see in the documentation:
public abstract void onItemClick (AdapterView parent, View view,
int position, long id)
Callback method to be invoked when an item in this AdapterView has
been clicked.
Implementers can call getItemAtPosition(position) if they need to
access the data associated with the selected item.
Parameters parent The AdapterView where the click happened. view The
view within the AdapterView that was clicked (this will be a view
provided by the adapter) position The position of the view in the
adapter. id The row id of the item that was clicked.
So in your case, the position of the clicked item is the arg2 value. Your code should be like this:
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Toast.makeText(getActivity(), arg2+"", Toast.LENGTH_LONG).show();
/*...*/
}
EDIT:
To get the Item, you can do like this:
(Item) arg0.getAdapter().getItem(arg2);
TL;DR
You can see in this case that it is important to use good names for parameters. With the default names given by Eclipse - or by others IDEs - this line:
(Item) arg0.getAdapter().getItem(arg2);
looks pretty strange. But if you are using the Android names - which gives you onItemClick(AdapterView<Item> parent, View view, int position, long id) - the line becomes:
(Item) parent.getAdapter().getItem(position);
Which is clearer and easier to use.
this should work:
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(getApplicationContext(), "Selected item at position: " + position, Toast.LENGTH_LONG).show();
}
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Intent i1 = new Intent(getApplicationContext(), Plaeeng.class);
// List<ScanResult> wifiList;
// i1.putExtra("cuor", );
// startActivity(i1);
Toast.makeText(ListCours.this, "=>"+parent.getAdapter().getItem(position), 5000).show();
}
});
You are doing well in setOnItemClickListener
the problem its the autocomplete its not working well in parameters you should have something like this:
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
}
});
the position is in your arg2, and as a tip you can get the item you click using this snippet:
parent.getAdapter().getItem(position);