I am setting a shuffled arraylist in grid view after rearranging i want to get the arraylist in the order it is there in gridview . i used getChildAt(position) but it is returning a view.
Here is my code:
for (int i = 0; i < smallimages.size(); i++) {
// ArrayList<View>bh=new ArrayList<>(9);
beforeshuffle.add(smallimages.get(i));
// SmallImageAdapter ad=new SmallImageAdapter(c,beforeshuffle);
}
Collections.shuffle(smallimages);
image_grid.setAdapter(new SmallImageAdapter(this, smallimages));
// image_grid.setAdapter(new SmallImageAdapter());
image_grid.setNumColumns((int) Math.sqrt(smallimages.size()));
image_grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
int counter = 0;
int firstclick;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
counter++;
if (counter % 2 == 0) {
firstclick = position;
Bitmap data1 = smallimages.get(position);
} else {
Bitmap swapImage = smallimages.get(position);
smallimages.set(position, smallimages.get(firstclick));
smallimages.set(firstclick, swapImage);
image_grid.invalidateViews();
}
// ArrayList<View>h=new ArrayList<View>(9);
for (int i=0;i<smallimages.size();i++) {
aftershuffle.set(i, smallimages.get(i));
}
}
});
this aftershulffle is not in the same order the images are place in the
grid view. So when i check
beforeshuffle.get(1).sameAs(aftershuffle.get(1))
it returns false
You can use setTag() and getTag() on the view to store custom class objects , For ex: imageView.setTag(person).
Later you can call Person person = (Person)getChildAt(position).getTag()
https://developer.android.com/reference/android/view/View.html#setTag(java.lang.Object)
Related
I am using spinner and listview concurrently, I have some logic that when i scroll on list i have have a data indication that tells which values to set on spinner, and i m using
spinner.setSelection(somePosition);
and when I click on Spinner it has also some data which indicate that to set the position of
listView.setSelection(somePosition);
Problem is that when i m scrolling on listView and in my adapter i need to change the postion of spinner selected item it calls the method
spinnerSurah.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int clickPosition, long l) {
int skipTotal = 0;
for(int i = 0 ; i < clickPosition ; i++)
{
SafeJSONObject surahObject = jsonArraySurahList.getJSONObject(i);
skipTotal+= surahObject.getInt("ayas");
}
SafeJSONObject surahObject = jsonArraySurahList.getJSONObject(clickPosition);
Log.e("spinnerSurah","spinnerSurah surahObject "+surahObject.toString());
positionSelection = skipTotal;
listView.setSelection(positionSelection);
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
Help me, I need to just change the postion of spinner without calling its listener.
You could set a condition in your listener that bypasses the selection logic if the ListView selection is called from the listener.
Declare a boolean in your class:
boolean skip_listener = false;
and change your listener to
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int clickPosition, long l) {
if(skip_listener){skip_listener = !skip_listener;return;}
int skipTotal = 0;
for(int i = 0 ; i < clickPosition ; i++)
{
SafeJSONObject surahObject = jsonArraySurahList.getJSONObject(i);
skipTotal+= surahObject.getInt("ayas");
}
SafeJSONObject surahObject = jsonArraySurahList.getJSONObject(clickPosition);
Log.e("spinnerSurah","spinnerSurah surahObject "+surahObject.toString());
positionSelection = skipTotal;
skip_listener = true;
listView.setSelection(positionSelection);
}
}
I am using a normal ListView (mItemsList) with expandable animation (from this tutorial). It works, when I click on list item it expands and shows details for this item.
mItemsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
View details = view.findViewById(R.id.details);
// Creating the expand animation for the item
ExpandAnimation expandAni = new ExpandAnimation(details, 500);
// Start the animation on the toolbar
details.startAnimation(expandAni);
}
});
I created a showDetails button and I want to expand all list items after clicking the button, but I am completely lost. Code below doesn't work
mShowDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mItemsList.getAdapter().getCount(); i++) {
View details= v.findViewById(R.id.details);
details.startAnimation(new ExpandAnimation(details, 500));
}
}
});
Could you help me?
Here's my list_item xml file
Maybe do the similar approach like the following to automatically click item one by one to open all listciew.
mShowDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mItemsList.getAdapter().getCount(); i++) {
listView.performItemClick(
getViewByPosition(i),
i,
listView.getAdapter().getItemId(i));
}
}
});
//the listview getChildAt only return the view(item) that is visible,
//therefore add a function to get invisible view together
public View getViewByPosition(int position) {
int firstItemPosition = listView.getFirstVisiblePosition();
int lastItemPosition = firstItemPosition + listView.getChildCount() - 1;
if (position < firstItemPosition || position > lastItemPosition ) {//is invisible
return listView.getAdapter().getView(position, null, listView);
} else {
int childIndex = position - firstItemPosition;//is visible
return listView.getChildAt(childIndex);
}
}
The one you do is not work as the view is refering the mShowDetailsButton ,but not mItemsList. Thus, you cannot findViewof id R.id.details.
mShowDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {//<-- this view not referring to mItemsList
}
});
In my home activity. I have listview with id list and textview with id count.
Here's the code:
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int count = 0;
for (int i = 0; i <= list.getLastVisiblePosition(); i++) {
if (list.getChildAt(i) != null) {
count++;
counter.setText(count + "");
}
}
I want to display in textview of rows in listview
Do you want to display how many items is in ListView or visible on screen?
For first option:
If you use ListView, then you have to use some ListAdapter (for example descendant of BaseAdapter or ArrayAdapter) which has method
getCount()
This returns, how many items is in adapter and also in ListView.
edit:
TextView countTextView; // here you want to set number of items
ListView lv; // your ListView
BaseAdapter adapter; // your adapter, that is used with ListView
// call this method in some listener
private void showNumberOfItems() {
int count = adapter.getCount();
countTextView.setText(String.valueOf(count));
}
You can use getLastVisiblePosition() method to count the number of rows,
int count=0;
for(int i = 0; i <= list.getLastVisiblePosition(); i++)
{
if(list.getChildAt(i)!= null)
{
count++; // saying that view that counts is the one that is not null, because sometimes you have partially visible items....
}
}
and then set the Text,
counter.setText(count + "");
Edit-
try something like this,
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int count = 0;
for (int i = 0; i <= list.getLastVisiblePosition(); i++) {
if (list.getChildAt(i) != null) {
count++;
}
}
counter.setText(count + "");
After filter a listview,how can I obtain the position of the first listview?
I use simpleadapter to fill the listview.
Each item in the datasource has its own id,and I use "case" to redirect them.
After I filter the listview ,I don't know how to associate the latter items with the first listview.The postion and id have changed.
Thank you.
I use the afterTextChanged of EditTextView to filter the listview and notify it.
#Override
public void afterTextChanged(Editable paramEditable) {
listItemsCopy.clear();
int count=simpleAdapter.getCount();
if ((count>0 )&¶mEditable.length()>0) {
for (int i = 0; i < simpleAdapter.getCount(); i++) {
Map<String,Object> tempMap=(Map<String,Object>)simpleAdapter.getItem(i);
String itemName=tempMap.get("name").toString();
HashMap<String, Object> tempHashMap=new HashMap<String, Object>();
int copyCount=0;
if(itemName.toLowerCase().contains(paramEditable.toString().toLowerCase())){
tempHashMap=(HashMap<String, Object>)simpleAdapter.getItem(i);
listItemsCopy.add(tempHashMap);
copyCount++;
}
}
if(listItemsCopy!=null){
Handler handler=new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
simpleAdaptercopy = new SimpleAdapter(getActivity(),
listItemsCopy, R.layout.right_menu_list_view, new String[] {
"name", "id", "image" }, new int[] {
R.id.rightMenuListViewTextView1,
R.id.rightMenuListViewTextView2,
R.id.rightMenuListViewImageView1 });
simpleAdapter.setViewBinder(new ViewBinder() {
#Override
public boolean setViewValue(View view, Object data,
String textRepresentation) {
if ((view instanceof ImageView && data instanceof Bitmap)) {
ImageView iv = (ImageView) view;
iv.setImageBitmap((Bitmap) data);
return true;
} else {
return false;
}
}
});
listView.setAdapter(simpleAdaptercopy);
simpleAdapter.notifyDataSetChanged();
}
}, 1000);
}
}
else {
listView.setAdapter(simpleAdapter);
simpleAdapter.notifyDataSetChanged();
}
}
Then I want to use the method onItemClick of listview to redirect different Intent.As the datasource has changed,both position and id are different from which I want
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent intent = null;
switch (position) {}`
I slove it with three arrays. Only test code:
String positionString[]=new String[22];
int latterPosition[]=new int[22];
for (int i = 0; i < latterPosition.length; i++) {
positionString[i]="";
latterPosition[i]=0;
}
int latterCount=0;
for (int i = 0; i < positions.length; i++) {
if (positions[i]==10) {
positionString[latterCount]=i+"";
latterPosition[latterCount]=10;
latterCount++;
}
}
this happens becouse Android gives you only IDs for the itmes you currently see + maybe two hidden on button and two hidden on top.
In this tutorial you can see how to create a ListView with a model, this helps me, when i got this problem before. Add this to you code and change it (I think you don't need the checkboxes).
I've created a ListView that in each row has a button with UP and DOWN arrow. Pressing these buttons makes the row to be shifted one position up or down.
I've achieved it by implementing OnClickListener for both buttons in a the override method getView. It works as it should however I fill bad with that cuz it seems to be highly memory consuming and lots of code is doubled.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = inflater.inflate(R.layout.row_layout, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
CheckBox checkBox = (CheckBox) rowView.findViewById(R.id.checkbox);
checkBoxes.add(position, checkBox);
String address = this.getItem(position).getAddress();
String tokenizedAddress = tokenizeAddress(address);
textView.setText(tokenizedAddress);
ImageButton buttonUp = (ImageButton)rowView.findViewById(R.id.button_up);
ImageButton buttonDown = (ImageButton)rowView.findViewById(R.id.button_down);
buttonUp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
ListAdapter adapter = ListAdapter.this;
if(position != 0 ){
GameTask current = adapter.getItem(position);
ArrayList<GameTask> list = new ArrayList<GameTask>();
for( int i = 0; i < adapter.getCount(); i++ )
list.add(adapter.getItem(i));
list.remove(position);
list.add(position-1, current);
adapter.clear();
for( int i = 0; i < list.size(); i++ ){
adapter.add(list.get(i));
}
adapter.notifyDataSetChanged();
}
}
});
buttonDown.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
ListAdapter adapter = ListAdapter.this;
if(position != adapter.getCount()-1 ){
GameTask current = adapter.getItem(position);
ArrayList<GameTask> list = new ArrayList<GameTask>();
for( int i = 0; i < adapter.getCount(); i++ )
list.add(adapter.getItem(i));
list.remove(position);
list.add(position+1, current);
adapter.clear();
for( int i = 0; i < list.size(); i++ ){
adapter.add(list.get(i));
}
adapter.notifyDataSetChanged();
}
}
});
return rowView;
}
Both listeners do almost the same, the only difference is the condition and the value of shifting +1/-1. I was wondering about creating the inner class implementing OnClickListener in the extended ArrayAdapter class however, I have no idea, how I could then pass the position of the row clicked to this inner class.
Instead of adding and removing elements from your ArrayList, you can better implement Collections.swap(List list, int firstElementIndex, int secondElementIndex) it would be much easier as you don't have to iterate through the whole Collection. A simple example for the same can be found here.
You could make a method that would be used by both buttonUp and buttonDown. This method could take as a parameter the type of action that was pressed (UP/DOWN), and the position of item in ListView, and then call this method in both of your click listener passing the appropriate action.
Example:
// 2 new constants
private static final int UP = 0;
private static final int DOWN = 1;
// Based on "type", increment or decrement the position.
private void changeRow(int type, int position){
if(type==UP){
position=position-1;
}else if(type==DOWN){
position=position+1;
}
// ........
// Then in your "for" cicle you specify:
list.add(position, current);
// ........
}
Then in the onClick() method of buttonUp you specify:
changeRow(UP, position);
and for buttonDown:
changeRow(DOWN, position);
This can be easily achieved
The way to do this is to store the data to be displayed in an List
Then when the user clicks the up or down arrow
Swap the references of data items which are shifting position using Collections.swap(List, int, int)
Then call notifyDataSetChanged on the adapter