My activity has a ListView that has a custom ArrayAdapter.
On my ArrayAdapter i have an image, a bunch of textboxes and a button.
On the getView of the adapter i get my button and set setOnClickListener. From the click listener i can get the index of the clicked item.
Now my problem is that i want to propagate that information to my main activity, where i want to handle my button click.
I can save the index information in a static var, but i still don't know how to fire an event in my activity.
How do i do that?
I'm 6 days new to Android so, thanks
iggy
Code:
My Activity:
public class MyClass extends Activity{
...
public void onCreate(Bundle savedInstanceState) {
...
myListView = (ListView)findViewById(R.id.lvxml);
myList = new MyCustomArrayAdapter(this, myAnotherClassObject);
myListView .setAdapter(myList);
...
}
}
Now in my Adapter
public class MyCustomArrayAdapter extends ArrayAdapter<myAnotherClass> {
...
....
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Button b = (Button)convertView.findViewById(R.id.myButtonInListView);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doStuff;
}
});
}
}
I need to somehow fire a buttonclick from my main activity, but without loosing the possibility to read the index clicked in the list view.
Here's an alternative and, what I think to be, more elegant solution.
Firstly, in your MyCustomArrayAdapter class, define an interface:
public interface MyCustomRowButtonListener{
void onCustomRowButtonClick(MyAnotherClass selectedItem, int position, View view);
}
Create an member variable of MyCustomRowButtonListener in your ArrayAdapter
public class MyCustomArrayAdapter{
private MyCustomRowButtonListener mRowButtonListener;
//....
}
and add a parameter for the listener in the constructor
public MyCustomArrayAdapter(Context context, MyCustomRowButtonListener listener){
mContext = context;
mRowButtonListener = listener;
}
in the getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Button b = (Button)convertView.findViewById(R.id.myButtonInListView);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mRowButtonListener.onCustomRowButtonClick(getItem(position),position,b);
}
});
}
and in your activity:
myList = new MyCustomArrayAdapter(this, myAnotherClassObject,this);
Now let your activity implement MyCustomRowButtonListener
public class MyClass extends Activity implements MyCustomRowButtonListener{
...
public void onCreate(Bundle savedInstanceState) {
...
myListView = (ListView)findViewById(R.id.lvxml);
myList = new MyCustomArrayAdapter(this, myAnotherClassObject,this);
myListView .setAdapter(myList);
...
}
}
public void onCustomRowButtonClick(MyAnotherClass selectedItem, int position, View view){
Toast.makeText(this,"You have selected "+selectedItem,Toast.LENGTH_SHORT).show();
}
So I've solved it somehow. It's probably not the way to do it but it works.
I save my activity in a static var.
Button b = (Button)convertView.findViewById(R.id.myButtonInListView);
b.setTag(position);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int i = (Integer) v.getTag();
myStaticVarRep.myActivity.myMethod(i);
}
});
The index ist the position variable.
Ist has to be final to use it here
public View getView(final int position, View convertView, ViewGroup parent)
You can inform your Activity with a listener-interface.
I'm going to assume your code looks a little like this.
public class <Your Class> ... implements OnClickListener{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.
.
.
button.setOnClickListener(this);
}
}
To handle button click events, you need to have an onClick method that looks like this.
public void onClick(View v){
<Handle your button click in here>
}
Whenever you click your button, it'll invoke the onClick method. That is where you would manipulate your static var, fire off other methods, etc. I hope that helps.
Related
In my Android application I have used an Activity and Adapter for list view, my acquirement is need to communicate both adapter class and activity via event listener using EventBus, so that I have created two event listener classes.
My process is:
1) I have a button in the activity,the button should communicate Adapter class.
2) If I click text view (text view widgets of list view) should communicate Activity class.
By the following code it works for Adapter communicates with Activity but Activity does not communicates with adapter class. Please help me on how to communicates for both the classes?
I have posted my full sample project code:
Activity class:
public class ListMobileActivity extends Activity {....};
private ListView list;
private Button btn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(ListMobileActivity.this);
......
list.setAdapter(adapter);
// Does not communicates with Adapter.
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
EventBus.getDefault().post(new TestEvent2("test event"));
}
});
}
public void onEvent(TestFinishedEvent event) {
Log.e("TestFinishEvent ", event.test);
}
}
Adapter class:
public class MobileArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public MobileArrayAdapter(Context context, String[] values) {
super(context, R.layout.list_mobile, values);
this.context = context;
this.values = values;
EventBus.getDefault().register(this.context); // registered here.
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_mobile, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
textView.setText(values[position]);
.........
// its works, communicate with Activity
textView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
EventBus.getDefault().post(new TestFinishedEvent("ssds"));
}
});
return rowView;
}
public void onEvent(TestEvent2 event) {
Log.e("Test event 2 ", event.test);
}
}
Don't create new EventBus instance each time, use EventBus.getDefault().
Add to both classes method public void onEvent(Object event)
In your MobileArrayAdapter constructor
change
EventBus.getDefault().register(this.context)
to
EventBus.getDefault().register(this)
Edit 1:
Also be aware, that you always should call EventBus.getDefault().unregister(this);
once you don't need to receive events or activity is beeing stopped/destroyed
Your activity must register to EventBus.
In your Activity class
Suscribe in on onStart()
Unsuscribe in onStop()
In your adapter
Just pour your event, all suscriber receive your post event.
How to make AdapterView.OnItemClickListener() work, when
... activity implements View.OnLongClickListener, View.OnClickListener,
DragDropPresenter,
View.OnTouchListener { ... }
and I there is
public void onClick(View v) {
// TODO Auto-generated method stub
}
to handle clicks?
Idea is that drag and drop is activated on a long click, and the OnItemClickListener method is used on a short click. Is it even possible?
Your question is a bit simplified but I hope that the example below will be helpful:
public class MainActivity extends Activity implements OnClickListener, OnItemClickListener, OnItemLongClickListener {
....
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
.....
listView.setAdapter(adapter);
listView.setOnItemLongClickListener(this);
listView.setOnItemClickListener(this);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
.....
}
#Override
public boolean onItemLongClick (AdapterView<?> parent, View item, int position, long id) {
....
}
I overcame the problem of handling short clicks by assigning each cell a tag and then reading the tag with the simple onClick listener:
public void onClick(View v) {
Integer position = (Integer)v.getTag();
if (position = ...){ do some stuff }
}
My ExpandableListView has some EditText boxes and Buttons(It's a sign-in/register screen).
I want to use an onClick function with a switch case to select the button that has been clicked and do something with them.
For the Buttons, I can't set the onClickListener.
All this is in the Custom Expandable List Adapter Class than I wrote.
I know there is another way to address a normal function in a Custom Expandable List Adapter but I don't know how.
Here's the relevant snippets of code WITHIN CustomExpandableAdapter class :
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
v = null;
position = 0;
position=getChildId(groupPosition, childPosition);
* - - unrelated code - *
if(position==2) //Draws Forgot Button
{
v = inflater.inflate(R.layout.forgot, parent, false);
View forgot = v.findViewById(R.id.fpb);
//What goes here to setOnClickListener?
}
return v;
}
public void onClick(View w) {
PopupWindow pw= new PopupWindow(inflater.inflate(R.layout.popup_layout, null, false),220,160, true);;
switch(w.getId())
{
case R.id.fpb:
{
pw.showAtLocation(v, Gravity.CENTER, 0, 0);
}
}
Can someone pleases help out??
I hope you have implemented OnClickListner in your adapter. If yes, then what error were you getting when using forgot.setOnClickListener(this);
Alrighty...you need to set OnClickListener not on the view, but on the specific buttons. So-you need to findViewByID(find the EditBox, Buttons or whatever) IN that View forgot and then set onClickListener ON them.
Such as...
Button b = forgot.findViewByID("myButton");
b.setOnClickListener(new OnClickListener {
etc...
Be sure to use the right OnClickListener, there are two in the API!:)
A better solution might exist, but here's what I do:
1. Interface
import android.view.View;
public interface RecyclerViewClickListener {
public void recyclerViewListClicked(View v);
}
2. In your Activity/Fragment
public class MyFragment(or Activity) Fragment implements RecyclerViewClickListener {
It will show an error that methods are not implemented. Add them
#Override public void recyclerViewListClicked(View v) {
YourObject mObject = (YourObject) v.getTag();
Log.i("My Object with >>> ", String.valueOf(mObject.getId()));
}
3. In your Adapter in the consturctor add at the end
public ExpandListViewAdapter(FragmentActivity context, etc. etc., RecyclerViewClickListener clickListener)
4. In your Adapter in getChildView()
button1.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
v.setTag(YourObject);
clickListener.recyclerViewListClicked(v);
}
});
I have an Android application with a ListView in it, the ListView will setup fine but now I want a image in the ListView to be clickable. I do this by using 2 classes, the Activity class (parent) and an ArrayAdapter to fill the list. In the ArrayAdapter I implement a OnClickListener for the image in the list that I want to be clickable.
So far it all works.
But now I want to run a function from the activity class when the onClick, for the image in the list, is run but I do not know how. Below are the 2 classes that I use.
First the Activity class:
public class parent_class extends Activity implements OnClickListener, OnItemClickListener
{
child_class_list myList;
ListView myListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// setup the Homelist data
myList = new child_class_list (this, Group_Names, Group_Dates);
myListView = (ListView) findViewById(R.id.list);
// set the HomeList
myListView.setAdapter( myList );
myListView.setOnItemClickListener(this);
}
void function_to_run()
{
// I want to run this function from the LiscView Onclick
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
// do something
}
}
And the ArrayAdapter from where I want to call a function from the Activity class:
public class child_class_list extends ArrayAdapter<String>
{
// private
private final Context context;
private String[] mName;
private String[] mDate;
public child_class_list (Context context, String[] Name, String[] Date)
{
super(context, R.layout.l_home, GroupName);
this.context = context;
this.mName = Name;
this.mDate = Date;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.l_home, parent, false);
ImageView selectable_image = (ImageView) rowView.findViewById(R.id.l_selectable_image);
selectable_image.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
// I want to run the function_to_run() function from the parant class here
}
}
);
// get the textID's
TextView tvName = (TextView) rowView.findViewById(R.id.l_name);
TextView tvDate = (TextView) rowView.findViewById(R.id.l_date);
// set the text
tvName.setText (mName[position]);
tvDate.setText (mDate[position]);
return rowView;
}
}
If anyone knows how to run the function in the activity class from the arrayadapter or how to set the image onClickListener in the Activity Class I would greatly apriciate the help.
Inside onClick() Do something like this:
((ParentClass) context).functionToRun();
Just for clarity to expand on provided answers
In a BaseAdapter you can get the parent class by calling this.getActivity();If you then typecast this to the actual activity class you can then call a function as per #AdilSoomro answer below so you actually end up with something like this
public class MyAdapter extends BaseAdapter<Long> {
public MyAdapter(Activity activity,
TreeStateManager<Long> treeStateManager, int numberOfLevels) {
super(activity, treeStateManager, numberOfLevels);
}
#Override
public void handleItemClick(final View view, final Object id) {
((MyActivity) this.activity).someFunction();
}
}
Then just declare someFunction in MyActivity to do what you want
protected void someFunction(){
// Do something here
}
If I have 2 or more listviews in one activity,then how do I use a onclicklistener? I mean How do I know on which one of them the user click?
public void onItemClick(AdapterView parent, View v, int position, long id) {
}
The above code is what I used,however when I try to use another listview,I just can't find a way to detect which listview is clicked.
Any ideeas to solve this?
In this case, the parent is the listView from which the itemClick originated. So what you can do is keep a member variable for each ListView and compare the parent to those members to see which list triggered the click.
So here's a simple class with what I mean:
public class MyTest extends Activity{
private ListView list1;
private ListView list2;
public void onCreate(Bundle b){
super.onCreate(b);
list1 = new ListView();
list2 = new ListView(); //or findViewById if you declared them in your layout
//the rest of your creation code here
}
public void onItemClick(AdapterView parent, View v, int position, long id) {
if(list1 == parent){
//handle list1 click
}else{
//handle list 2 click
}
}
}
There are two ways you can do it.
Implement OnItemClickListener
public class ListViewTest extends Activity implements OnItemClickListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
if(view ==myListView)1{
}
if(view ==myListView){
}
}
}
Set your own listener
myListView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO: click on second listview
}
});
You can do it as this:
listView1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO: click on first listview
}
});
listView2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO: click on second listview
}
});
its pretty simple ,
only one list can act as the official list under a ListActivity and this list (and only this list) should have the special list id (#android:list i think) so just set the id of the other list to some other id and set its setOnItemClickListener to do whatever you want. I currently work on an app with 2 listViews and an additional list Fragment.