listview - access to non-visible items - android

I would like to check which of elements on my listview is also a member of another list and check all of them (by changing background). But the only way I can think of is:
for (String str : list1){
if (list2.contains(str)) {
lv.getChildAt(adapter.getPosition(str)).setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
}
}
But that works only for visible elements of the list and throws null pointer exception when accessing non-visible elements. What can I do to apply changes for all list items? Do I have to write my own adapter or maybe there is any "equivalent" of getChiledAt but working for all elements of the listview not only visible ones?

I didn't try by myself, but a suggestion. Can you please try this way, and check.
Idea is to use setOnScrollListener with onScroll method and to have null check inside for loop.
It's not good solution though, because for loop working on every scroll.
lv.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
for (String str : list1) {
if (list2.contains(str)) {
if (lv.getChildAt(adapter.getPosition(str)) != null) {
lv.getChildAt(adapter.getPosition(str))
.setBackgroundColor(
getResources()
.getColor(
android.R.color.darker_gray));
}
}
}
}
});

The solution was to use onScroll method (as Chitrang suggested) and set everything only for visible item. Android Magic works, everything works fine, also for non-visible items :)
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
for (int i = lv.getFirstVisiblePosition(); i<=lv.getLastVisiblePosition(); i++){
if (list2.contains(lv.getItemAtPosition(i).toString()))
lv.getChildAt(i - lv.getFirstVisiblePosition()).setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
}
}
}

You can create a new List, with the (i assume you have) id like the listview's data.
Example :
You have class Person with int id, String name. Create a new List<Integer> to store all (not just the visible one) of your listview's person id, normally by using the listview's adapter.

Related

Drag-drop not working in nhaarman's ListviewAnimation library

I am using nhaarman's ListviewAnimation library https://github.com/nhaarman/ListViewAnimations which works great.
But I am facing following issues:
The main problem I am facing is, I am not able to debug my code. I have directly copy/pasted the four required libraries into libs folder. Placing a debug point inside any of the listview methods like onItemLongClick() does not work.
The second problem is, drag-drop listView is not working in my code. Whenever I try to drag any list item, on dropping the list item, the item takes the same position from which it was dragged.
Here's the code I have used:
listview.enableDragAndDrop();
listview.setDraggableManager(new TouchViewDraggableManager(
R.id.list_row_draganddrop_textview));
listview.setOnItemMovedListener(this);
listview.setOnItemLongClickListener(this);
#Override
public void onItemMoved(final int originalPosition, final int newPosition) {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), "Moved"
+ swingBottomInAnimationAdapter.getItem(newPosition)
+ newPosition, Toast.LENGTH_SHORT);
mToast.show();
}
#Override
public boolean onItemLongClick(final AdapterView<?> parent,
final View view, final int position, final long id) {
if (listview != null) {
listview.startDragging(position - listview.getHeaderViewsCount());
}
return true;
}
Whenever I try to drag any list item, on dropping the list item, the item takes the same position from which it was dragged.
Of course. Handling the change in position is your responsibility, and you should take care of it inside the onItemMoved callback:
#Override
public void onItemMoved(final int originalPosition, final int newPosition) {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), "Moved"
+ swingBottomInAnimationAdapter.getItem(newPosition)
+ newPosition, Toast.LENGTH_SHORT);
mToast.show();
// Adapt the following to your implementation
if (originalPosition != newPosition) {
YourObject item = (YourObject) yourAdapter.getItem(originalPosition);
yourAdapter.moveItem(item, newPosition);
}
}
The method mentioned above would look something like:
public void moveItem(YourObject item, int newIndex) {
if (mEntries != null) {
mEntries.remove(item);
mEntries.add(newIndex, item);
notifyDataSetChanged();
}
}
If you go through the source code, you'll see that what you are dragging around is a Bitmap. The list item is sitting at its original position.
For others having the same problem - Niek Haarman has answered this question on GitHub here.
Don't see GitHub going down soon, but as it is good tone to paste the answer too, here it is:
#Override
public long getItemId(int position) {
return position;
}
#Override
public boolean hasStableIds() {
return true;
}
position is not a stable id here. You need a stable id for the item
which does not depend on the position.
use
import com.nhaarman.listviewanimations.ArrayAdapter;
instead of
import android.widget.ArrayAdapter;
that is the reason it doesn't calling onItemMoved

Spinner Android (SetPrompt)

I am running into an issue with a spinner that I defined and bound to an array resource. The problem is that it "ONLY" defaults to the first item of the array when it is first constructed. I am using the setPrompt and it looks like it is being ignore totally. I wrote to the log and I can see in the log that I am setting it to the right value but it instead keeps defaulting to the first element in the array.
_spnCountDown.setPrompt(setting);
Log.d("SETTING_SPINNER", setting);
_spnCountDown.setOnItemSelectedListener(new OnItemSelectedListener()
{
boolean _firstTime = true;
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3)
{
if (_firstTime == false)
{
String value = _spnCountDown.getSelectedItem().toString();
MobileAppManager.getInstance().storeSetting("CountDown",
value);
Log.d("SETTING_SPINNER onItemSelected", value);
}
else
{
Log.d("SETTING_SPINNER onItemSelected", "Ignore");
_spnCountDown.setPrompt(Settings.this.getInitialCountDown());
_firstTime = false;
}
}
public void onNothingSelected(AdapterView<?> arg0)
{
// TODO Auto-generated method stub
}
});
I have followed few answers that recommend using a flag to overcome the fact that onSetItemSelected will first the first time the spinner is constructed. So, rightfully so, I am ignoring the first call. However as I mentioned, It is defaulting to first entry.
So, If this line will not do anything _spnCountDown.setPrompt("5 seconds")
I'm not sure but if I understand your question correctly this suggests perhaps you should use setSelection?
Setting default values in spinner in android

Android ListView : How to keep the ListView at the top when its content changes?

I have a view that contains a ListView which is bound to a cursor adapter. When The cursor content change I want to keep the ListView at the top then in my custom cursor adapter I added :
#Override
protected void onContentChanged() {
// ...
myListView.scrollTo(0, 0);
}
but this doesn't work. Then I read somewhere to queue this action like this :
myListView.post(new Runnable() {
public void run() {
myListView.scrollTo(0, 0);
}
});
but this doesn't work either.
How can I keep the ListView at the top when its content changes?
EDIT:
Just for try, I added a button and called scrollTo() in its onClickListener and it didn't work! What am I missing ?
Instead of scrollTo, try setSelection(0) to get to the top position of list view.
i made functions that could be useful for others for listview scrolling, they work for me in every android version, emulator and device, here itemheight is the fixed height of view in the listview.
int itemheight=60;
public void scrollToY(int position)
{
int item=(int)Math.floor(position/itemheight);
int scroll=(int) ((item*itemheight)-position);
this.setSelectionFromTop(item, scroll);// Important
}
public void scrollByY(int position)
{
position+=getListScrollY();
int item=(int)Math.floor(position/itemheight);
int scroll=(int) ((item*itemheight)-position);
this.setSelectionFromTop(item, scroll);// Important
}
public int getListScrollY()
{
try{
//int tempscroll=this.getFirstVisiblePosition()*itemheight;// Important
View v=this.getChildAt(0);
int tempscroll=(this.getFirstVisiblePosition()*itemheight)-v.getTop();// Important
return tempscroll;
}catch(Exception e){}
return 0;
}
ListView's scrollTo applies to the ListView it self as a View
setSelection(0) does the trick because it applies to the listview's adapter

Is there a cleaner approach to click listeners in Android?

So I have been developing in Android for quite some time and I am natively a .Net developer. The problem I am facing is that my code looks awful, and I really dislike the way that Java\Android not sure which, makes click events appear in code. In this example below I have a List View with a click event.
list_view.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
});
In .Net I would have set my click event in my Initialize Components method and then implemented it in my main code page. How do I tell android to use a click event method below in my code instead of referencing it right there. Maybe something like this?
list_view.setOnItemClickListener(onItemClick());
Later on in my code page.
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
});
All in all I am just looking for a cleaner approach to wiring my events up to my controls so I can read the code better. It is a struggle moving to Java and Android when originally being a .Net developer.
Thanks!
Edit
Thank you for the answer below I posted my work here.
list_view.setOnItemClickListener(list_view_onItemClickListener);
//below in my code
private OnItemClickListener list_view_onItemClickListener = new OnItemClickListener (){
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
};
you can try this!
you may like or not but what approach i found best for me is for example this is your layout.xml
<Button1 android:id="#+id/btn1" android:onClick="btnHandle">
</Button1>
<Button2 android:id="#+id/btn2 android:onClick="btnHandle">
</Button2>
and in your activity.Java
public void btnHandle(View v)
{
if(v.getId()==R.id.btn1){
}else if(v.getId()==R.id.btn2){
}
by this approach you dont have to implement any interface and even if you change your Button view to ImageView still you dont have to do any thing in code. but in case of setOnClickListener you have to change your instance variable type from Button to ImageView.
}

On scroll change using list-view Android

I am developing an application which consists on scroll-change-listener,Here is my problem, I am getting the Number of items for the server.Until here every thing works fine to me.
1.IF i am showing the 10 values in the list-view,that 10 values only should stream.
2.When Scroll state is changed the reaming item should hit server.
3.Below is my code .
#Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
if (visibleItemCount < 1)
return;
streaming.clear();
int firstPoisitionValue = symbolList.getFirstVisiblePosition();
int lastPositionValue = symbolList.getLastVisiblePosition();
WatchListData row;
String symbol;
for (int i = firstPoisitionValue; i <= lastPositionValue; i++) {
row = model.get(i);
symbol=row.getSymbol();
Log.w("Hello Android", "Symbol Value ::>"+symbol);
streaming.add(symbol);
}
if (streamFlag) {
System.out.println("calling the request");
streamingRequest("quote", streamingSymbols);
streamFlag = false;
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
pauseStreaming();
if(scrollState == SCROLL_STATE_IDLE){
streamingRequest("quote", streamingSymbols);
}
Thanks,
Nikhilreddy.
You can do this by using onScroll Listener. Using this listener When scroll reaches the end you can load new items to the list. refer this link. It may help you.Dynamic listView

Categories

Resources