• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Listview OnItemLongClick and getView [SOLVED]

timcs

Member
Hi

I am struggling to get my onItemLongClick Listener to be used with the simple cursor adapter getView. The onItemClick Listener which is also part of the app does interact with the getView but the LongClick does not

My Activity is a ListActivity :

Code:
public class MainActivity extends ListActivity

I get the ListView as follows :

Code:
 final ListView datalist = getListView();

The long click is set to this listview as follows :

Code:
datalist.setLongClickable(true);

 datalist.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// TODO Auto-generated method stub
				isclick = false;
				islongclick = true;
				
				
				return false;
			}});
I use the booleans as a last resort thinking this would help when it reaches the getView which looks as follows :

Code:
public View getView(int position,View convertView, ViewGroup parent) {
				//Toast.makeText(getApplicationContext(), "Long Cick Reached Get View Method.... ", Toast.LENGTH_LONG).show();
				 View row = super.getView(position, convertView, parent);
				//View row = convertView;
				
				if (row == null) {
					LayoutInflater grow;
					grow = LayoutInflater.from(getBaseContext());
					row = grow.inflate(R.layout.viewdata, null);
					row.setLongClickable(true);
					((TableLayout)row.findViewById(R.id.Table1)).setLongClickable(true);
					((TableLayout)row.findViewById(R.id.Table2)).setLongClickable(true);
					((TableLayout)row.findViewById(R.id.Table3)).setLongClickable(true);
				}

if (islongclick) {
				Toast.makeText(getApplicationContext(), "Long Cick Reached Get View Method.... ", Toast.LENGTH_LONG).show();
				if (!longrowclick.equals(-1)) {
					Toast.makeText(getApplicationContext(), "Long Cick Row - moving to previous row..... ", Toast.LENGTH_LONG).show();
				//   datalist.smoothScrollToPosition(longrowclick);
				   mC.moveToPosition(longrowclick);
				   ((TableLayout)row.findViewById(R.id.Table1)).setBackgroundColor(Color.BLACK);
					((TableLayout)row.findViewById(R.id.Table2)).setBackgroundColor(Color.BLACK);
					((TableLayout)row.findViewById(R.id.Table3)).setBackgroundColor(Color.BLACK);
				}
			
				mC.moveToPosition(position);
				if (mC.getPosition()==position ) {
				((TableLayout)row.findViewById(R.id.Table1)).setBackgroundResource(R.drawable.darkslateblue);
				((TableLayout)row.findViewById(R.id.Table2)).setBackgroundResource(R.drawable.darkslateblue);
				((TableLayout)row.findViewById(R.id.Table3)).setBackgroundResource(R.drawable.darkslateblue);
				} 
				longrowclick = position;
			}
		return row;
		
			}

My goal here is trying to highlight the bespoke row (made up of a linearlayout and several tables) when a long press occurs. I can get this to happen if the code in the getView sits in the onItemLongClick method but then the row selected stays selected if another is then chosen.

Also tried the suggestions from this post but keeping with the idea of using the onitemlonglick :
android - Items in ListView not long clickable after setting click listener in getView() - Stack Overflow
Please help

Thanks

TimCS
 
Since posting this question I worked out how to call the getview method by using the notifydatasetchanged from the adapter. My only problem now is that when the selected row is "long clicked" it always seems to choose the first row. Then when another row is selected , I cannot unselected the first row

Thanks

TimCS
 
Welcome to the the fun of ListViews and touch events.

Dont pay attention to that stack overflow link, I dont even know what they hell they were talking about. dont use gesture detector, that's for something else entirely.

One easy idea to use as a rule of thumb is that the ___ItemClickListeners apply to the ListView, and should not be used at the same time as a onClickListener attached from a getView(). This will keep things more straight forward.


getView() 's purpose is to create and recycle rows. If you need multiple buttons within the row, then use the regular View.OnClickListener.

If you want to use the onItemClick, make sure the rows and their child views are not "textIsSelectable" or "focusable"

Finally, when highlighting something, it's a good idea to understand how a ListAdapter is meant to recycle views. getView() is not really meant for you to use to get a reference to a view and manipulate it. Rather it's a delegate that the system calls when running the ListView for you.

so here is a simple example that assume your row is just a TextView
Code:
//class fields in the adapter
private int selectedPosition = -1;
List<String> myDataList = new ArrayList<String>();


// call some method to add some data to use...
myDataList.add("Jan");
myDataList.add("Feb");
myDataList.add("Mar");
myDataList.add("Apr");
myDataList.add("May");
myDataList.add("Jun");
myDataList.add("Jul");
myDataList.add("Aug");
myDataList.add("Sept");
myDataList.add("Oct");
myDataList.add("Nov");

public View getView(int position, View convertView, ViewGroup parent) 
{
    if (convertView==null)
    {
        //inflate a new View

         LayoutInflater inflater = (LayoutInflater) getContext()
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        convertView= inflater.inflate(R.layout.mylayout, null);
        convertView.setText( myDataList.get( position) );
    }
    else
    {
        //just bind to the incoming view, 
        //the system passed us a view to recycle for performance

        convertView.setText( myDataList.get( position) );
    }

    if (selectedItem==position)
    {
            convertView.setBackgroundColor(Color.RED);
    }
    else
    {
           convertView.setBackgroundColor(Color.GREEN);
     }
    return convertView;

}
Then in your click listener just change the value of selectedPosition and call notifyDataSetChanged();


 
Welcome to the the fun of ListViews and touch events.

Dont pay attention to that stack overflow link, I dont even know what they hell they were talking about. dont use gesture detector, that's for something else entirely.

One easy idea to use as a rule of thumb is that the ___ItemClickListeners apply to the ListView, and should not be used at the same time as a onClickListener attached from a getView(). This will keep things more straight forward.


getView() 's purpose is to create and recycle rows. If you need multiple buttons within the row, then use the regular View.OnClickListener.

If you want to use the onItemClick, make sure the rows and their child views are not "textIsSelectable" or "focusable"

Finally, when highlighting something, it's a good idea to understand how a ListAdapter is meant to recycle views. getView() is not really meant for you to use to get a reference to a view and manipulate it. Rather it's a delegate that the system calls when running the ListView for you.

so here is a simple example that assume your row is just a TextView
Code:
//class fields in the adapter
private int selectedPosition = -1;
List<String> myDataList = new ArrayList<String>();


// call some method to add some data to use...
myDataList.add("Jan");
myDataList.add("Feb");
myDataList.add("Mar");
myDataList.add("Apr");
myDataList.add("May");
myDataList.add("Jun");
myDataList.add("Jul");
myDataList.add("Aug");
myDataList.add("Sept");
myDataList.add("Oct");
myDataList.add("Nov");

public View getView(int position, View convertView, ViewGroup parent) 
{
    if (convertView==null)
    {
        //inflate a new View

         LayoutInflater inflater = (LayoutInflater) getContext()
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        convertView= inflater.inflate(R.layout.mylayout, null);
        convertView.setText( myDataList.get( position) );
    }
    else
    {
        //just bind to the incoming view, 
        //the system passed us a view to recycle for performance

        convertView.setText( myDataList.get( position) );
    }

    if (selectedItem==position)
    {
            convertView.setBackgroundColor(Color.RED);
    }
    else
    {
           convertView.setBackgroundColor(Color.GREEN);
     }
    return convertView;

}
Then in your click listener just change the value of selectedPosition and call notifyDataSetChanged();



alostpacket , thanks for your reply. My row layout is a little bit more than just a textview, it has an imageview, and at least 6 textviews.

My question on your reply is how does the getview method you have provided get called. I am working on a ListActivity class and using the onItemLongclickListener instead of the onitemclicklistener as well.

Finally I am using a simplecursoradapter to read the data in not an arrayadapter so I am trying to work out from your example how to incorporate the code you have provide.

** EDIT **

Looking at you code again looks very much the same as mine, however my get view is part of the simplecursoradapter, is this were it should be ? I am using a variable to hold the position long clicked in the onitemLongclick, and comparing this to the position variable in the get view but they never seem to match


Thanks

TimCS
 
getView() is called by the Android OS when it is running/displaying a ListView

It's not meant for you to call. It's a delegate method where the OS is asking YOU to provide a view for the ListView.

When you call notifyDataSetChanged() it SHOULD refresh all the views calling getView for each one it needs. If this is not happening, we should focus on this part. It's not related to the item click listeners.

Does that help clear some of it up?
 
getView() is called by the Android OS when it is running/displaying a ListView

It's not meant for you to call. It's a delegate method where the OS is asking YOU to provide a view for the ListView.

When you call notifyDataSetChanged() it SHOULD refresh all the views calling getView for each one it needs. If this is not happening, we should focus on this part. It's not related to the item click listeners.

Does that help clear some of it up?

So I am putting the getview as a public method within the ListActivity instead of being part of the simplecursoradpater then?

Thanks

TimCS
 
getView() is a method you must override on your Adapter that gets called behind the scenes by the ListView/Android OS


One thing that might be confusing you is the way the cursor may not refresh. It looks like you are manually moving a cursor? Do you not have a content:// Uri?

Though for just highlighting a view, all you should need to do is call notifyDataSetChanged()

Basically, when you call notifyDataSetChanged() Android will do the complicated work of looking through all the items in the ListView and refreshing the data displayed in them by calling getView() on your Adapter with the position of each row it needs to display. Your part of the "contract" is to return an up-to-date view from getView().

This is why it's ok to keep a field in the Adapter to manage which position should be highlighted.

(Side note, a ListActivity is just an Activity with a ListView already integrated).
 
getView() is a method you must override on your Adapter that gets called behind the scenes by the ListView/Android OS


One thing that might be confusing you is the way the cursor may not refresh. It looks like you are manually moving a cursor? Do you not have a content:// Uri?

Though for just highlighting a view, all you should need to do is call notifyDataSetChanged()

Basically, when you call notifyDataSetChanged() Android will do the complicated work of looking through all the items in the ListView and refreshing the data displayed in them by calling getView() on your Adapter with the position of each row it needs to display. Your part of the "contract" is to return an up-to-date view from getView().

This is why it's ok to keep a field in the Adapter to manage which position should be highlighted.

(Side note, a ListActivity is just an Activity with a ListView already integrated).

My simplecursoradapter is defined using this method:

[HIGH] adapter = new SimpleCursorAdapter(this,R.layout.viewdata, mC, fields, viewfields)[/HIGH]

mC is the cursor .

I do have a variable that keeps track of the position clicked but this is a global variable that starts of as -1 and then whenever the ItemLongClicklistner is triggered this then becomes the position selected.

Thanks

TimCS
 
Ahhh... right, sorry I should have noticed you said SimpleCursorAdapter.

SimpleCusorAdapter has its own already fully implemented getView(), that's probably why you are confused about where to put/call getView().

In other words, there is no getView() method for you to work with when using a SimpleCursorAdapter.

You should use the regular CursorAdapter (or BaseAdapter) if you want to override getView()

SimpleCursorAdapter is designed for people who dont want to code the adapter part. It is also meant for very simple rows (generally).

(Unless you are using a ViewBinder, but it doesnt sound like this is what you are doing).
 
Ahhh... right, sorry I should have noticed you said SimpleCursorAdapter.

SimpleCusorAdapter has its own already fully implemented getView(), that's probably why you are confused about where to put/call getView().

In other words, there is no getView() method for you to work with when using a SimpleCursorAdapter.

You should use the regular CursorAdapter (or BaseAdapter) if you want to override getView()

SimpleCursorAdapter is designed for people who dont want to code the adapter part. It is also meant for very simple rows (generally).

(Unless you are using a ViewBinder, but it doesnt sound like this is what you are doing).

I am actually using a setviewbinder within the simplecursoradapter to display a separator between days of the month etc. Can I use this to achieve the highlighting of a row?


Thanks

TimCS
 
I dont think a ViewBinder can do that, no.

I think you may want to look at extending CursorAdapter.

Okay - as you said that link is a little advanced for me and doesn't seem to mention about extending a cursoradapter.

I will look around on the net for examples.

Thanks


TimCS
 
Hmm, actually I suppose you could try having a custom view in your list row with an ID (like R.id.row_background) and change the color of that via the setViewValue() method in your ViewBinder (assuming your ViewBinder has access to the variable of the "selectedPosition" integer you save).

Is your ViewBinder a static inner class? Can you post the code for the ViewBinder and your row XML?

Then every time setViewValue is called, you should set the color to "not selected" unless the position matches. And make sure to call notifyDataSetChanged when onItemLongClick is called.

This might actually do the trick for you.
 
Hmm, actually I suppose you could try having a custom view in your list row with an ID (like R.id.row_background) and change the color of that via the setViewValue() method in your ViewBinder (assuming your ViewBinder has access to the variable of the "selectedPosition" integer you save).

Is your ViewBinder a static inner class? Can you post the code for the ViewBinder and your row XML?

Then every time setViewValue is called, you should set the color to "not selected" unless the position matches. And make sure to call notifyDataSetChanged when onItemLongClick is called.

This might actually do the trick for you.

My Row is as follows, I have probably gone too far with the tables I have used but I could not see how else to achieve the way I positioned everything. Yes you will ask why I have formatted the dates this way, it is because I am (and I need it to do this) storing the day month and year in separate fields:



[HIGH] <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff000000"
android:longClickable="true"
>


<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>

<TextView
android:id="@+id/seper"
android:textColor="@android:color/white"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/listSeparatorTextViewStyle"
android:background="#ff444444"


/>








<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="2"
android:background="#ff000000"
android:id="@+id/Table1"
>

<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >


<ImageView
android:id="@+id/image_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Image of type"
android:src="@drawable/app_icon"
/>

<TextView
android:id="@+id/type_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Baby Gate Slammed"
android:textColor="#ffffffff"
android:layout_marginLeft="5dp"
/>


</TableRow>

<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:background="#ff000000"
android:id="@+id/Table2"
>
<TableRow
android:id="@+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/info_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A lot of Arguing swearing and shouting "
android:textColor="#ffffffff"
/>

</TableRow>
</TableLayout>
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="10"
android:background="#ff000000"
android:id="@+id/Table3"
>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/date_day_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="01"
android:textColor="#ffffffff"
/>
<TextView
android:id="@+id/date_separator1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/"
android:textColor="#ffffffff"
/>
<TextView
android:id="@+id/date_month_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="12"
android:textColor="#ffffffff"
/>
<TextView
android:id="@+id/date_seprator2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/"
android:textColor="#ffffffff"
/>
<TextView
android:id="@+id/date_year_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2012"
android:textColor="#ffffffff"
/>

<TextView
android:id="@+id/time_hour_view"
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00"
android:textColor="#ffffffff"
/>

<TextView
android:id="@+id/time_separator1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffffff"
android:text=":" />

<TextView
android:id="@+id/time_min_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffffff"
android:text="00" />

<TextView
android:id="@+id/time_separator2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffffff"
android:text=":" />
<TextView
android:id="@+id/time_sec_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffffff"
android:text="00" />

</TableRow>


</TableLayout>

</TableLayout>
</TableLayout>
</LinearLayout>
[/HIGH]


and here is the code from the viewbinder :

[HIGH]adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {

@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
// TODO Auto-generated method stub



if (view.getId()==R.id.seper) {
Integer prevrowday = 0, prevrowmonth = 0 , prevrowyear=0;
Integer currowdate = cursor.getInt(cursor.getColumnIndex("day"));
Integer currowmonth = cursor.getInt(cursor.getColumnIndex("month"));
Integer currowyear = cursor.getInt(cursor.getColumnIndex("year"));
Integer currdatesort = cursor.getInt(cursor.getColumnIndex("date_sort"));

String daystr="",monthstr="";
((TextView)view).setVisibility(View.INVISIBLE);

if (cursor.getPosition()==0) {

daystr = prefixzero(currowdate);
monthstr = months(currowmonth);

((TextView)view).setText(daystr+" "+monthstr+" "+String.valueOf(currowyear));
((TextView)view).setVisibility(View.VISIBLE);

}

if (cursor.getPosition()>0 && cursor.moveToPrevious()) {

prevrowday = cursor.getInt(cursor.getColumnIndex("day"));
prevrowmonth = cursor.getInt(cursor.getColumnIndex("month"));
prevrowyear = cursor.getInt(cursor.getColumnIndex("year"));

cursor.moveToNext();

if ((prevrowday == null || !prevrowday.equals(currowdate)) || (prevrowmonth == null || !prevrowmonth.equals(currowmonth))|| (prevrowyear == null || !prevrowyear.equals(currowyear))) {
daystr = prefixzero(currowdate);
monthstr = months(currowmonth);
((TextView)view).setText(daystr+" "+monthstr+" "+String.valueOf(currowyear));

((TextView)view).setVisibility(View.VISIBLE);

} else{
((TextView)view).setVisibility(View.INVISIBLE);
}
}

return true;
}




String imgreference = cursor.getString(cursor.getColumnIndex("image_desc"));
if (view instanceof ImageView ) {

int imgres = getResources().getIdentifier(imgreference, null, null);
((ImageView)view).setImageResource(imgres);
return true;
}

if (view.getId()==R.id.type_view) {
int imgtext = cursor.getInt(cursor.getColumnIndex("type_id"));
((TextView)view).setText(vnoiseimage[imgtext]);
return true;
}

if (view.getId()==R.id.date_day_view) {
Integer daydataconv = cursor.getInt(cursor.getColumnIndex("day"));
String dayconv =prefixzero(daydataconv);

((TextView)view).setText(dayconv);

return true;
}
if (view.getId()==R.id.date_month_view) {
Integer monthdataconv = cursor.getInt(cursor.getColumnIndex("month"));
String monconv =prefixzero(monthdataconv);

((TextView)view).setText(monconv);
return true;
}

if (view.getId()==R.id.time_hour_view) {
Integer hourdataconv = cursor.getInt(cursor.getColumnIndex("hour"));
String hourconv =prefixzero(hourdataconv);

((TextView)view).setText(hourconv);
return true;
}

if (view.getId()==R.id.time_min_view) {
Integer mindataconv = cursor.getInt(cursor.getColumnIndex("min"));
String minconv =prefixzero(mindataconv);

((TextView)view).setText(minconv);
return true;
}





if (view.getId()==R.id.time_sec_view) {
Integer secdataconv = cursor.getInt(cursor.getColumnIndex("second"));
String secconv =prefixzero(secdataconv);

((TextView)view).setText(secconv);
return true;
}
return false;

}

});
[/HIGH]


Thanks

TimCS
 
So you are trying to change the background of the whole row? And keeping track of what is selected by an integer in the Activity?



If that is correct, then you can give the root LinearLayout of the row an ID (R.id.row_root_layout or something) and change the background of that based on the integer.

Something like

[HIGH]if (view.getId()==R.id.row_root_layout)
{
if (selected == position)
{
//set color
}
else
{
//remove color
}
}[/HIGH]Then make sure to call adapter.notifyDataSetCahnged() every time you get a click
 
So you are trying to change the background of the whole row? And keeping track of what is selected by an integer in the Activity?



If that is correct, then you can give the root LinearLayout of the row an ID (R.id.row_root_layout or something) and change the background of that based on the integer.

Something like

[HIGH]if (view.getId()==R.id.row_root_layout)
{
if (selected == position)
{
//set color
}
else
{
//remove color
}
}[/HIGH]Then make sure to call adapter.notifyDataSetCahnged() every time you get a click

Hi alostpacket - tried your suggestion but my only query is where the position variable comes from, because I did not know, I tried using the cursor.getPosition()==selected but no highlighted row occurs and adding a Toast statement within the if statement is not called either so I know it means that these two are not becoming true. I am still calling the notifyDataSetCahnged() from within the onItemLongClickListener and the position from that method is then retained in the selected variable.

Any thoughts would be appreciated.

Thanks

TimCS
 
Ah sorry, usually those types of methods have a "position" parameter.

You tried the right work around, but what did cursor.getPosition() return? Can you just log that?
 
Ah sorry, usually those types of methods have a "position" parameter.

You tried the right work around, but what did cursor.getPosition() return? Can you just log that?

It doesn't even reach that condition, in fact it does not even seem to reach another test I put. When the OnItemLongClick is triggered, I used a boolean variable to true, so in this code, I put the following to see if it reached this area :

[HIGH]if (islongclick) {
Toast.makeText(getApplicationContext(), "reached islongclick within view getid row_layout ", Toast.LENGTH_LONG).show();
}[/HIGH]

However this never happens, I also noticed that the other view.getid checks returned true so I tried this as well but I still do not get any Toast message coming up .

Thanks

TimCS
 
skip the if check and try using LogCat

Are you programming in Eclipse?

You should be able to do

Log.d("MyTAG", "cursor position is=" +cursor.getPosition() );

Have you used LogCat before?
 
skip the if check and try using LogCat

Are you programming in Eclipse?

You should be able to do

Log.d("MyTAG", "cursor position is=" +cursor.getPosition() );

Have you used LogCat before?

Yes using Eclipse and Yes used logcat. I will add a few log.d's and report back

Thanks

TimCS
 
When adding the log.d("MYTAG","Reached View ID") method it does not record it under debug or verbose in the logcat logs.

Here is what my viewbinder code is (row_layout is the ID of the linearLayout) (longrowclick1 is the selected position from onItemLongClickListener) :


[HIGH] if (view.getId()==R.id.row_layout) {

Log.d("ROW_GETID","Reached view Get ID Row Layout");
if (islongclick) {
Toast.makeText(getApplicationContext(), "reached islongclick within view getid row_layout ", Toast.LENGTH_LONG).show();
}
Log.d("ROW_GETPOS","cursor POS="+cursor.getPosition());
if (cursor.getPosition()==longrowclick1 ) {

cursor.moveToPosition(longrowclick1);
Toast.makeText(getApplicationContext(), "Now Marking Row with LongRowClick1= "+Integer.toString(longrowclick1) +"Now Marking row on Long Row Click 1= "+Integer.toString(longrowclick1), Toast.LENGTH_LONG).show();
((TableLayout)view.findViewById(R.id.Table1)).setBackgroundResource(R.drawable.darkslateblue);
((TableLayout)view.findViewById(R.id.Table2)).setBackgroundResource(R.drawable.darkslateblue);
((TableLayout)view.findViewById(R.id.Table3)).setBackgroundResource(R.drawable.darkslateblue);
} else {
((TableLayout)view.findViewById(R.id.Table1)).setBackgroundColor(Color.BLACK);
((TableLayout)view.findViewById(R.id.Table2)).setBackgroundColor(Color.BLACK);
((TableLayout)view.findViewById(R.id.Table3)).setBackgroundColor(Color.BLACK);

}
return true; // I have set this to false and removed this line also


} [/HIGH]

Just in case here is the code form onItemLongClickListener :

[HIGH]datalist.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub

islongclick = true; // backup check
longrowclick1 = arg2; // Gets the selected position
adapter.notifyDataSetChanged(); // refreshes the adapter

return false; // have to do this to make the menucontext appear
}});
[/HIGH]
 
Can you move this line outside of the if ?

[HIGH]Log.d("ROW_GETPOS","cursor POS="+cursor.getPosition()); [/HIGH]It sounds like the adapter is not refreshing the views (this can happen if it thinks no data has really changed in the cursor)

And if it thinks that, it wont call setViewValue again, even though you told it "notifyDataSetCahnged()"

Cursors can be a bit weird like that unfortunately. (This is often why it is suggested you use a ContentProvider and Uri instead of a raw Cursor)


edit:

also you should log this so you know exactly which view is getting the click event.

[HIGH]
Log.d("ROW_GETID","view clicked was: "+view);
[/HIGH]You may need to set the root LinearLayout in your row as clickable=true in the XML, and make everything else focusable=false and focusableInTouchMode=false


if that doesnt work try removing the clickable=true, but leaving everything else in the row as non-focusable
 
Can you move this line outside of the if ?

[HIGH]Log.d("ROW_GETPOS","cursor POS="+cursor.getPosition()); [/HIGH]It sounds like the adapter is not refreshing the views (this can happen if it thinks no data has really changed in the cursor)

And if it thinks that, it wont call setViewValue again, even though you told it "notifyDataSetCahnged()"

Cursors can be a bit weird like that unfortunately. (This is often why it is suggested you use a ContentProvider and Uri instead of a raw Cursor)


edit:

also you should log this so you know exactly which view is getting the click event.

[HIGH]
Log.d("ROW_GETID","view clicked was: "+view);
[/HIGH]You may need to set the root LinearLayout in your row as clickable=true in the XML, and make everything else focusable=false and focusableInTouchMode=false


if that doesnt work try removing the clickable=true, but leaving everything else in the row as non-focusable

Okay with place the log.d outside of the If and add the view statement as suggested.

the LinearLayout should be set to LongClickable=true as this is what I am trying to achieve but I didn't do the focusable and focusableInTouchMode to false so I will try these also.

Not going to be able to do this until around after 1pm now.

Otherwise - would the custom simplecursoradapter approach still work? I did do something similar with a Listview that shows files and directories but that was using the click not long click and it didn't involve a layout view with the amount of objects that this does.

Thanks

TimCS
 
As suggested i have set all other objects in the layout to false on the two focusable settings

I then tried the clickable=true and removed this in the LinearLayout section. It does not highlight the row but as instructed, I put a log.d in the setviewvalue method and it does get called when doing a longclick but does not go into the IF part very strange....

Also added the log.d to show the object being longclicked - seems to be textview and imageview however these are set to android:focusable="false" and android:focusableInTouchMode="false"


Further to this as there is only one imageview object I tried using the view.getid()==R.id.image_view but now where it crashes with a null point exception is when I am trying to change the background colours so in this method, using the way I did in getview does not work.



Thanks

TimCS
 
Back
Top Bottom