I have a class that extends ListActivity where the list items respond to OnClick events. Adding an OnItemLongClickListener does not work. The onItemLongClick() function is not called (no log-output or Toast showing) but the normal OnClick() event is handled instead.
I want to display a contextual action bar upon long click. A minimum example using my code in a new project works fine. So my question is: What can possibly prevent the onItemLongClick() trigger from being triggered?
My minimum API is 11. I am also setting the listView to longClickable="true".
Activity code (selected functions):
public class EventListActivity extends ListActivity {
private ArrayList<Event> arrEvents = null;
private ArrayAdapter<Event> adpEvents = null;
private ActionMode mActionMode = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// only create list adapter and set it
arrEvents = new ArrayList<Event>();
adpEvents = new ArrayAdapter<Event>(this, android.R.layout.simple_list_item_activated_2, android.R.id.text1, arrEvents) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
TextView text2 = (TextView) view.findViewById(android.R.id.text2);
text1.setText(arrEvents.get(position).getTitle());
text2.setText(arrEvents.get(position).getDateTimeFormatted());
return view;
}
};
setListAdapter(adpEvents);
// add CAB to ListView
setupCAB();
}
#Override
protected void onResume() {
super.onResume();
// populate list and refresh adapter
createEventList();
adpEvents.notifyDataSetChanged();
// if list empty show emtpy msg, otherwise hide it
setContentView(R.layout.activity_event_list);
TextView empty = (TextView) findViewById(R.id.text_empty);
if(arrEvents.isEmpty()) {
empty.setVisibility(View.VISIBLE);
} else {
empty.setVisibility(View.GONE);
}
}
private void setupCAB() {
// Important: to select single mode
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
// Called when the user long-clicks an item on the list
#Override
public boolean onItemLongClick(AdapterView<?> parent, View row, int position, long rowid) {
Log.w("EventListActivity", "Long click detected!");
Toast.makeText(EventListActivity.this, "Long click detected!", Toast.LENGTH_SHORT).show();
if (mActionMode != null) {
return false;
}
// Important: to mark the editing row as activated
getListView().setItemChecked(position, true);
// Start the CAB using the ActionMode.Callback defined above
mActionMode = EventListActivity.this.startActionMode(mActionModeCallback);
return true;
}
});
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.event_context, menu);
return true;
}
// Called when the user enters the action mode
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Disable the list to avoid selecting other elements while editing one
EventListActivity.this.getListView().setEnabled(false);
return true; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.mnu_share_event:
//TODO share event
mode.finish();
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
// Re-enable the list after edition
EventListActivity.this.getListView().setEnabled(true);
mActionMode = null;
}
};
}
activity_event_list.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=".EventListActivity" >
<TextView
android:id="#+id/text_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="45dp"
android:text="#string/empty"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="gone" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:longClickable="true" >
</ListView>
</RelativeLayout>
If you have buttons responding to onClick() events inside your listview, you need to set the following in the container holding those buttons:
android:descendantFocusability="blocksDescendants"
If what you have are textviews, the problem is slightly trickier. See this: Focusable EditText inside ListView
This answer does not solve user1's question but the symptoms were similar my problem (i.e. OnItemClickListener was getting called but OnItemLongClickListener was not). I'm posting my answer here in case anyone else stumbles on this question like I did when trying to solve my problem.
I was using a ListView inside a Fragment and implemented the listener methods:
public class MyFragment extends Fragment implements OnClickListener,
OnLongClickListener, OnItemClickListener, OnItemLongClickListener {
Here is the onItemClick method that was working fine:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long rowId) {
Log.i("Chimee", "short click working");
}
And here is the onItemLongClick method that wasn't firing:
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
long rowId) {
Log.i("Chimee", "Long click working");
return false;
}
Of course the simple answer was that I forgot to setOnItemLongClickListener. I added it after the setOnItemClickListener that I had all along and then it worked fine.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.my_fragment, container, false);
lvSuggestions = (ListView) v.findViewById(R.id.lvSuggestions);
lvSuggestions.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lvSuggestions.setOnItemClickListener(this);
lvSuggestions.setOnItemLongClickListener(this); // Forgot this
...
}
When using a ListActivity or ListFragment there is no method you can override for the long-click, and getting access to the ListView is not possible in onCreateView(), since it is being controlled by the parent class.
So, to overcome this, I did this, since the getListView() command won't work until after the view is created:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecipeListView = this.getListView();
mRecipeListView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View view, int position, long row_id) {
// Process the long-click
}
});
}
Related
I have implemented a list View with CheckedTextView . When I am selecting a particular row and clicking on checkbox then checkbox becomes invisible. Also sometimes any other row get selected.I want to select multiple items.
please help...
List_row Layout is..
<CheckedTextView
android:id="#+id/service_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="20sp"
android:layout_marginBottom="10dp"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:textColor="#000000"
android:checked= "false"
>
CustomListView is:
import java.util.ArrayList;
public class CustomListView extends ArrayAdapter {
//to reference the Activity
private final Activity context;
String value;
//to store the list items
private final String[] nameArray;
CheckedTextView nameTextField;
public CustomListView(Activity context, ArrayList nameArra) {
super(context, R.layout.row_list_view, nameArrayParam);
this.context = context;
this.nameArray = nameArrayParam;
}
public View getView(int position, View view, ViewGroup parent)
{
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.row_list_view, null, true);
//this code gets references to objects in the listview_row.xml file
nameTextField = (CheckedTextView)
rowView.findViewById(R.id.service_name);
//this code sets the values of the objects to values from the arrays
nameTextField.setText(nameArray[position]);
// perform on Click Event Listener on CheckedTextView
nameTextField.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v("customList",";clicked row is " +
nameTextField.getText().toString());
if (nameTextField.isChecked()) {
// set check mark drawable and set checked property to false
value = "un-Checked";
nameTextField.setCheckMarkDrawable(R.color.colorAccent);
nameTextField.setChecked(false);
}
else {
// set check mark drawable and set checked property to true
value = "Checked";
nameTextField.setChecked(true);
}
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
}
});
return rowView;
}
In my MainActivity.java, I have used listView setOnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
selected_Item = (String) arg0.getItemAtPosition(arg2);
Toast.makeText(AskForService.this, "Clicked item is" + selected_Item, Toast.LENGTH_LONG).show();
}
});
After implementing these code I can see -
ListView with checked TextView
ListView Can Scroll showing all the list items
on clicking a particular row..listview click listener is called and showing the Toast but checkbox becomes white(invisible) and sometimes another row get selected...Please help
Create a model class which contains a flag "isChecked" and set the data according to the model inside adapter
This link might be helpful : https://stackoverflow.com/a/40285759/8770539
Use an arraylist to store checked item's position.
call notifyDataSetChanged() for onclick()
Use this,
if(list.contains(position)) {
nameTextField.setChecked(true);
}
else {
nameTextField.setChecked(false);
}
nameTextField.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(list.contains(position))
{
list.remove(position);
}
else
{
list.add(position);
}
notifyDataSetChanged();
}
});
I have search on StackOverflow and other websites but no one can answer to my question.
I have a gridView with items. I have a button to add item to this gridView.Each element on the GridView is a relativeLayout with an Imageview and an EditText.
When i add item to the gridView using the button, I want to get my relativeLayout and request Focus on the editText to set a name on it.
Imagine i have 3 elements in my gridView.
I add element to my ArrayList and call adapter.notifiyDataSetChanged().
The new element is displayed on the grid but when i use getChildCount(), the gridView still has 3 children.
It cause problem because i want to request focus on the last added EditText.
How can i update my gridView object ?
Fragment :
//Get gridView
final GridView gridCat = (GridView) v.findViewById(R.id.gridCategory);
adapter = new GridCategoryAdapter(getActivity(), subcatList);
gridCat.setAdapter(adapter);
gridCat.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SubCategory subcat = subcatList.get(position);
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_middle, SubCategoryFragment.newInstance(subcat.getProducts(), subcat.getName()));
transaction.addToBackStack(null);
transaction.commit();
}
});
Button catAddButton = (Button) v.findViewById(R.id.catAddButton);
catAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "old size gridview : " + gridCat.getChildCount());
subcatList.add(new SubCategory());
Log.d(TAG, "new size list : " + subcatList.size());
adapter.notifyDataSetChanged();
Log.d(TAG, "new size gridview : " + gridCat.getChildCount());
//HERE : childCount is the same !
RelativeLayout rl = (RelativeLayout) gridCat.getChildAt(gridCat.getChildCount()-1);
rl.findViewById(R.id.subcatName).setFocusable(true);
rl.findViewById(R.id.subcatName).setLongClickable(true);
rl.findViewById(R.id.subcatName).requestFocus();
}
});
My Adapter :
public class GridCategoryAdapter extends BaseAdapter {
private static final String TAG = "com.zester.manager.ListViewSizeAndPriceAdapter";
private LayoutInflater mInflater;
private final Context context;
private ArrayList<SubCategory> listSubCat;
private ViewHolder holder;
public GridCategoryAdapter(Context context, ArrayList<SubCategory> values) {
super();
this.context = context;
listSubCat = values;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listSubCat.size();
}
#Override
public Object getItem(int position) {
return listSubCat.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.subcat_view, null);
holder = new ViewHolder();
holder.SubCatName = (EditText) convertView.findViewById(R.id.subcatName);
holder.imageSubCat = (ImageView) convertView.findViewById(R.id.imageSubCatView);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
SubCategory subCat = (SubCategory) getItem(position);
if (subCat != null) {
holder.SubCatName.setText(subCat.getName());
holder.imageSubCat.setImageDrawable(context.getResources().getDrawable(R.drawable.subcat_default));
}
return convertView;
}
static class ViewHolder {
public EditText SubCatName;
public ImageView imageSubCat;
}
}
XML for each item on the gridview :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/imageSubCatView"
android:src="#drawable/subcat_default"
android:layout_centerHorizontal="true"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/subcatName"
android:gravity="center_horizontal"
android:hint="Ex : Bières"
android:layout_marginTop="20dp"
android:layout_below="#+id/imageSubCatView"
android:background="#android:color/transparent"
android:singleLine="true"
android:focusable="false"
android:longClickable="false"/>
Thx a lot !
When i tried to get my RelativeLayout, null is return : RelativeLayout rl = (RelativeLayout) gridCat.getChildAt(gridCat.getCount()-1);
I think your answer is this:
when you add
subcatList.add(new SubCategory());
adapter.notifyDataSetChanged();
to your code it is not guaranteed that new view for them has been created, because it is possible that your gridView has 100 children and you are just looking at children from 7 to 20 , so new child at index 100 has not yet inflated because the getView is called upon request in order to save memory so when there is no need to show the 100th child, why it must be called? so relativelayout for that child is null because it has not inflated.
in catAddButton listener you must not touch any gridview item, because when the button click happens it first runs your listener then scrolls to the end of gridView so still you have problem, what sholud you do?
in class of SubCategory() put variable that indicates it has not shown for the first time. in getView of gridview each time you want to inflate new items look at that variable (in the list of your SubCategory at item list.get(position)) and for example if it is boolean toggle it to false so that means the new object is going to be seen by user. So in this way each time you are going to inflate the view you know that if it is the first time or not, if it is first time your boolean is true else it has already been false. if it is not first time remove focus else put focus by calling reqesFocuse.
I am showing a List in a ListView through a custom adapter SongsListAdapter.java with custom itemview music_item.xml and there is a method i want to call in my Activity Class MainActivity.java so i cannot use setOnClickListener method
what i did is i added an attribute to music_item.xml onClickto call method in MainActivity.java
but this is not working, by clicking the list item it is not invoking the method from Activity class
SongsListAdapter.java
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.music_item, null);
this.mView = view;
holder.title = (TextView) view.findViewById(R.id.songName);
holder.descr = (TextView) view.findViewById(R.id.songArtists);
holder.dp = (ImageView) view.findViewById(R.id.albumIcon);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.title.setText(SongsListItemslist.get(position).getDisplayName());
holder.descr.setText(SongsListItemslist.get(position).getArtist());
holder.dp.setImageBitmap(SongsListItemslist.get(position).getBitmap());
// Listen for ListView Item Click
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
return view;
}
MainActivity.java
public void songPicked(View view) {
Log.v("clicked", "clicked");
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
}
Music_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/card"
android:clickable="true"
android:onClick="songPicked" >
<ImageView
android:id="#+id/albumIcon"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="#drawable/abc_ab_bottom_solid_dark_holo" />
</RelativeLayout>
And i couldn't able to see clicked in my Logs..
Delete this from your SongsListAdapter.java
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
you are setting a onClick Listener with an empty action in your adapter that isn´t necessary, use only the method defined in your Layout:
android:onClick="songPicked"
You don't want to set a listener on the Layout of your list item Music_item. This will be covered under the setOnItemClickListener of your ListView.
see: setOnItemClickListener on custom ListView
Firstly you have to remove
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
and then if you want ot handle the click on the ListView you need to call this from the MainActivity
list.setAdapter(yourCustomAdapter);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.v("clicked", "clicked");
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
}
});
Don't forget to remove onClick attribute from the RelativLayout.
Good luck..
You say you cannot use setOnClickListener, I'm not sure why? In your adapter constructor, you can pass in the Activity, set it as a variable in your adapter class and use it in your on click listener to call a method defined in Activity.
Alternatively, use setOnItemClickListener in your activity or fragment (ie where you initially set the adapter).
I am new to Android so my question may seem ridiculous but I cant figure it out.
I started creating an app some time ago and using 'Create new Android Activity' usually created a .java and .xml file for it, and everything worked. Now, after update when I use 'Create new Android Activity' it creates .java with class (which now extends ActionBarActivity and not Activity as before) and it adds a fragment_nameofactivity.xml + all things to make it work like internal class extending Fragment...
Now I used to do some ListView display on the page and without a fragment it all works great, but when fragment got introduced I can no longer findViewById(R.id.list_view) if its inside a fragment...
My question is do I need to place my whole functionality inside the class extending Fragment? I tried but it didn't work... Or do I still write all my functionality in the original class and then somehow access the listView in the fragment...
Here is the code:
public class PlayersActivity extends ActionBarActivity {
PlayerDataDatabaseAdapter playerDataHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_players);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
playerDataHelper = new PlayerDataDatabaseAdapter(this);
playerDataHelper.open();
displayPlayersList();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.players, 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);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_players,
container, false);
return rootView;
}
}
private void displayPlayersList() {
Cursor cursor = playerDataHelper.getAllPlayers();
String [] columns = playerDataHelper.columnsToBind();
int [] to = new int[] {
R.id.player_name,
};
SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(this, R.layout.fragment_player_details, cursor, columns, to, 0);
ListView listView = (ListView) findViewById(R.id.players_list);
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
int player_id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
Intent intent = new Intent(PlayersActivity.this, EditPlayerActivity.class);
intent.putExtra("PlayerId", player_id);
startActivity(intent);
}
});
}
public void addNewPlayer(View view) {
Intent intent = new Intent(this, AddPlayerActivity.class);
startActivity(intent);
}
}
Fragment_players.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="uk.co.eximage.soccermum.PlayersActivity$PlaceholderFragment" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:text="#string/players"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal = "true"
android:layout_below="#+id/textView1"
android:onClick="addNewPlayer"
android:text="#string/add_player" />
<ListView
android:id="#+id/players_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/button1"
>
</ListView>
</RelativeLayout>
activity_players.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="uk.co.eximage.soccermum.PlayersActivity"
tools:ignore="MergeRootFrame" />
Running this returns NullPointerException on the line that tries to get players_list:
ListView listView = (ListView) findViewById(R.id.players_list);
after this listView is null.
What am I doing wrong?
And finally do I need fragments? Maybe I should just remove them and do it the 'old' way with one view per page?
You need to iniaitlize ListView in Fragment
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_players,
container, false);
listView = (ListView)rootView. findViewById(R.id.players_list);
playerDataHelper = new PlayerDataDatabaseAdapter(getActivity());
playerDataHelper.open();
displayPlayersList();
The ListView belongs to fragment_players.xml. Move all your code related to fragment in onCreateView.
Edit:
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_players,
container, false);
listView = (ListView)rootView. findViewById(R.id.players_list);
playerDataHelper = new PlayerDataDatabaseAdapter(getActivity());
playerDataHelper.open();
displayPlayersList();
return rootView;
}
private void displayPlayersList() {
Cursor cursor = playerDataHelper.getAllPlayers();
String [] columns = playerDataHelper.columnsToBind();
int [] to = new int[] {
R.id.player_name,
};
SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(getActivity(), R.layout.fragment_player_details, cursor, columns, to, 0);
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
int player_id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
Intent intent = new Intent(getActivity(), EditPlayerActivity.class);
intent.putExtra("PlayerId", player_id);
startActivity(intent);
}
});
}
}
Fragments were introduced to better support the tablet form factor. If you don't plan to rearrange your display (ie. show list and detail view together), you don't need fragments and can go the old way.
You should have to initialize Listview from fragment rootView
Either you have to Declare ListView globally and intialize inside onCreateView of Fragment or have to declare View rootView globally and initialize listview by
ListView listView = (ListView) rootView .findViewById(R.id.players_list);
I want to add a second on click to a ListViewItem.
I already created the View (ImageView) and i set the on Click. The function gets called.
But: How can i get the Informations of this ListViewItem? It would be enough to get the Position in the ListView?
The ImageView:
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:onClick="favorite"
android:src="#drawable/star" />
The code for my on click function:
public void favorite(View view){
ImageView iView = (ImageView) view;
iView.setImageResource(R.drawable.star_checked);
ViewParent v = iView.getParent();
}
Use an anonymous inner class:
ImageView iView = (ImageView) findViewById(R.id.imageView1);
iView.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
//Your code
}
});
myListView.setOnItemClickListener(new OnItemClickListener() { ![enter image description here][2]
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String value = myListView.getAdapter().getItem(position).toString(); // String value of the clicked item
//Code
}
});
If you want to make bigger applications you should think about better naming your components, 'imageView1' is not very handy. Name you components like 'imageview_main' or 'imageview_customerdetails'.
Subclass OnItemClickListener rather than OnClickListener.
Edit:
Okay I think I understand what you are trying to do now. I would subclass your ListAdapter and override the getView(int position, ...) method like so:
private OnClickListener mImgClickListener = new OnClickListener() {
#Override
public void onClick(View view) {
int position = (Integer) view.getTag();
// do stuff with position knowledge!
}
});
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
v = convertView;
} else {
v = newView(int position);
}
v.findViewById(R.id.imageView1).setTag(position);
return v;
}
private View newView(int position) {
View v;
// inflate your view here
View imageView = v.findViewById(R.id.imageView1);
imageView.setOnClickListener(mImgClickListener);
return v;
}
Of course, even better would be to implement the ViewHolder pattern in the getView method to eliminate expensive calls to findViewById.
I believe the View hierarchy will take care of giving priority to the click on the ImageView (rather than the list item as a whole), but I could be wrong.