RecyclerView index not updating while removing item using FirebaseRecycleradapter - android

I have implemented FirebaseRecyclerAdapter for a dynamic recyclerView and while I am trying to delete an item from the list, initially items at wrong indexes are getting deleted and after more items deletion, i am getting IndexOutOfBoundsException. I have already tried all solutions I found which can be seen as commented inside populateViewHolder() method. Please, if you have to downvote, at least give a proper answer and downvote it as I have already tried all solutions possible. Below I am posting my code. Please have a look.
Check the delete.setOnClickListener():
adapter = new FirebaseRecyclerAdapter<Slc, viewHolder>(
Slc.class,
R.layout.single_slc_row,
viewHolder.class,
FirebaseDatabase.getInstance().getReference().child("DCU")) {
#Override
protected void populateViewHolder(final viewHolder viewHolder, final Slc model, final int position)
{
//expand collapse
viewHolder.vis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
// ViewAnimationsUtils.expand(viewHolder.inv);
viewHolder.collapse.setVisibility(View.VISIBLE);
viewHolder.inv.setVisibility(View.VISIBLE);
}
});
viewHolder.collapse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
// ViewAnimationsUtils.collapse(inv);
viewHolder.inv.setVisibility(View.GONE);
viewHolder.collapse.setVisibility(View.GONE);
}
});
String s=adapter.getRef(position).getKey();
viewHolder.name.setText(s);
//dimming get
viewHolder.dimming.setProgress(model.getPercentage());
//on off get
if(model.getON_OFF()==1)
{
viewHolder.onOff.setChecked(true);
}
else if(model.getON_OFF()==0)
{
viewHolder.onOff.setChecked(false);
}
//dimming set
//viewHolder.dimming.incrementProgressBy(10);
viewHolder.showProgress.setText( viewHolder.dimming.getProgress()+"%");
viewHolder.dimming.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
if(position!=RecyclerView.NO_POSITION)
{
if(seekBar.isShown() && fromUser)
{
progress= (progress/10)*10;
adapter.getRef(position).child("Percentage").setValue(progress);
viewHolder.showProgress.setText(progress+"%");
}
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
viewHolder.onOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(buttonView.isPressed() &&isChecked){
adapter.getRef(position).child("ON_OFF").setValue(1);
}else{
adapter.getRef(position).child("ON_OFF").setValue(0);
}
}
});
viewHolder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
final Dialog dialog = new Dialog(myContext);
dialog.setTitle("Delete Slc?");
dialog.setContentView(R.layout.delete_slc);
dialog.setCancelable(false);
Window window = dialog.getWindow();
if(window == null) return;
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.CENTER;
dialog.getWindow().setAttributes(lp);
TextView delete = (TextView)dialog.findViewById(R.id.deleteSlc);
final String key= adapter.getRef(position).getKey();
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
// int pos = viewHolder.getAdapterPosition();
ref.child(key).setValue(null);
// int selectedItems = position;
// for (int i = selectedItems; i >= selectedItems; i--) {
// adapter.getRef(i).removeValue();
adapter.notifyItemRemoved(position);
// }
// adapter.getRef(position).removeValue();
//
// adapter.notifyItemRemoved(position);
// adapter.notifyDataSetChanged();
dialog.dismiss();
}
});
TextView dialogButton = (TextView) dialog.findViewById(R.id.canceld);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
dialog.dismiss();
}
});
dialog.show();
}
});
}
};
slcList.setAdapter(adapter);
The exception I am getting after deleting some items:
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.firebase.ui.database.FirebaseArray.getItem(FirebaseArray.java:52)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getRef(FirebaseRecyclerAdapter.java:150)

The error is caused by usage of position object inside of function not directly under populateViewHolder. Like in this one: (but not limited to)
protected void populateViewHolder(final viewHolder viewHolder, final Slc model, final int position) {
// here position object is valid
...
viewHolder.dimming.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged( ... ) {
// but here, position object is likely to be incorrect
// especially when you add/remove item of list
}
...
}
And the solution is simply to replace all the position objects that are not directly under populateViewHolder into viewHolder.getAdapterPosition().
Note: I copy it from my comment in case others seek for answer and miss the comment

Related

why is my onclick is messing up the code?

I have a button submit_house inside a navdraw that gets a onclick listener inside a different button's (add_house) onclick listener. submit_house is the button that ends the onclick of add_house and after that it gets a new onclick. yet for some reason the first submit_house onclick does not work ( the log command there really doesn't register). why is that?
code in main.java:
building_onclick = new View.OnClickListener() {
#Override
public void onClick(final View v) {
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
mMap.setOnMapClickListener(null);
// this line clears the arraylist
arrayList.clear();
// next thing you have to do is check if your adapter has changed
adapter.notifyDataSetChanged();
building.emptyBuilding();
//the navdraw
buildingViewNavdraw(add_house, houseList);
//launches drawer
// locks drawer from opening from swipes
navDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
// If the navigation drawer is not open then open it, if its already open then close it.
if(!navDrawer.isDrawerOpen(Gravity.RIGHT)) navDrawer.openDrawer(Gravity.RIGHT);
else navDrawer.closeDrawer(Gravity.LEFT);
//sets building latlng
building.setLat(point.latitude);
building.setLng(point.longitude);
building.setMarkerId(Double.toString(building.getLat()).replace(".","") + Double.toString(building.getLng()).replace(".",""));
View.OnClickListener add_houseOnClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
//TODO: create alert dialog to get apartment number
house.setApartment("1");
houseEditNavdraw(status, activists, familyNameEdit, addressEdit, descriptionEdit, currentStatusEdit, submit_house, add_report);
isHouseUploaded = false;
isInBuilding = true;
house.setType("House");
//copies over content from building to house
house.setLat(building.getLat());
house.setLng(building.getLng());
house.setMarkerId("A" + house.getApartment() + building.getMarkerId());
house.setLocation(building.getLocation());
currentStatusEdit.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
if (currentStatusEdit.getSelectedItem().toString().equals("קשר המשך")){
currentActivistsEdit.setVisibility(View.VISIBLE);
activists.setVisibility(View.VISIBLE);
currentActivists.setVisibility(View.INVISIBLE);
add_report.setVisibility(View.VISIBLE);
} else if (currentStatusEdit.getSelectedItem().toString().equals("לא מעוניינים") || currentStatusEdit.getSelectedItem().toString().equals("מעוניינים")){
currentActivists.setVisibility(View.INVISIBLE);
activists.setVisibility(View.INVISIBLE);
currentActivistsEdit.setVisibility(View.INVISIBLE);
add_report.setVisibility(View.VISIBLE);
} else if (currentStatusEdit.getSelectedItem().toString().equals("לא עונים")) {
currentActivists.setVisibility(View.INVISIBLE);
activists.setVisibility(View.INVISIBLE);
currentActivistsEdit.setVisibility(View.INVISIBLE);
add_report.setVisibility(View.INVISIBLE);
}
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
// this line adds the data of the apartmnet and puts in your array
arrayList.add(house.getApartment() + ": " + "משפחת " + house.getName());
// next thing you have to do is check if your adapter has changed
adapter.notifyDataSetChanged();
//sets the report onClicks
add_report.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
reportEditNavdraw(reportEdit, reportDateEdit, reportActivistsEdit, submit_report);
submit_report.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
houseEditNavdraw(status, activists, familyNameEdit, addressEdit, descriptionEdit, currentStatusEdit, submit_house, add_report);
if (currentStatusEdit.getSelectedItem().toString() == "קשר המשך"){
activists.setVisibility(View.VISIBLE);
currentActivistsEdit.setVisibility(View.VISIBLE);
}
Date date = new Date();
Report rpt = new Report(reportActivistsEdit.getText().toString(), reportEdit.getText().toString(), reportDateEdit.getText().toString());
reportNameList.add(house.getMarkerId() + date.toString().replace(" ", "").replace(":", "").replace("GMT+", "").replace(".",""));
reportList.add(rpt);
lastReport.setVisibility(View.VISIBLE);
lastReport.setText(reportEdit.getText());
reportActivistsTitle.setVisibility(View.VISIBLE);
reportActivists.setVisibility(View.VISIBLE);
reportActivists.setText(reportActivistsEdit.getText());
reportDateTitle.setVisibility(View.VISIBLE);
reportDate.setVisibility(View.VISIBLE);
reportDate.setText(reportDateEdit.getText());
reportEdit.setVisibility(View.INVISIBLE);
reportDateEdit.setVisibility(View.INVISIBLE);
reportActivistsEdit.setVisibility(View.INVISIBLE);
submit_report.setVisibility(View.INVISIBLE);
reportDateEdit.setText("");
reportActivistsEdit.setText("");
reportEdit.setText("");
}
});
}
});
submit_house.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO: add safeguards against partial input
//sets data for "blank" drawer
familyName.setText(familyNameEdit.getText());
familyNameEdit.setVisibility(View.INVISIBLE);
familyName.setVisibility(View.VISIBLE);
address.setText(addressEdit.getText());
addressEdit.setVisibility(View.INVISIBLE);
address.setVisibility(View.VISIBLE);
description.setText(descriptionEdit.getText());
descriptionEdit.setVisibility(View.INVISIBLE);
description.setVisibility(View.VISIBLE);
currentStatusEdit.setVisibility(View.INVISIBLE);
currentStatus.setText(currentStatusEdit.getSelectedItem().toString());
currentStatus.setVisibility(View.VISIBLE);
if (currentStatusEdit.getSelectedItem().toString() == "קשר המשך"){
currentActivists.setText(currentActivistsEdit.getText());
currentActivistsEdit.setVisibility(View.INVISIBLE);
currentActivists.setVisibility(View.VISIBLE);
activists.setVisibility(View.VISIBLE);
house.setActivists(currentActivists.getText().toString());
}
submit_report.setVisibility(View.INVISIBLE);
add_report.setVisibility(View.INVISIBLE);
currentStatusEdit.setSelection(0, false);
//setting all the values to house
house.setName(familyName.getText().toString());
house.setAddress(address.getText().toString());
house.setDescription(description.getText().toString());
house.setStatus(currentStatus.getText().toString());
//upload reports to db
if (reportNameList.size() != 0){
for (int i = 0; i < reportNameList.size(); i++){
mDatabase.child("reports").child(reportNameList.get(i)).setValue(reportList.get(i));
}
//sets the report list to the house
house.setReport(reportNameList);
house.setLatestReport(reportNameList.get(reportNameList.size() - 1));
//clears the lists for next use
reportNameList.clear();
reportList.clear();
}
mDatabase.child("houses").child(house.getLocation()).child(house.getMarkerId()).setValue(house);
house.emptyHouse();
isHouseUploaded = true;
building.addHouse(house.getMarkerId());
Log.d("here", building.getHouses().toString());
emptyNavdraw();
buildingViewNavdraw(add_house, houseList);
}
});
}
};
add_house.setOnClickListener(add_houseOnClick);
add_houseOnClick.onClick(v);
submit_house.setVisibility(View.VISIBLE);
add_house.setVisibility(View.INVISIBLE);
submit_house.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mDatabase.child("houses").child(building.getLocation()).child("B" + building.getMarkerId()).setValue(building);
LatLng latLng = new LatLng(building.getLat(), building.getLng());
Marker marker = mMap.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.building15x15)));
marker.setTag(building.getMarkerId());
building.emptyBuilding();
submit_house.setVisibility(View.INVISIBLE);
add_house.setVisibility(View.VISIBLE);
submit_house.setOnClickListener(null);
}
});
}
});
}
};
Implement your activity with View.OnClickListener interface.
It will implement a method with name onClick().
Now add this line in onCreate() method : submit_house.setOnClickListener(this);
And you can perform your work in onClick() as
public void onClick(View v)
{
if(v.id==R.id.submit_house)
{
//
}
}
But you cannot perform two different functions on a single button. For that
you have to use internal variable to identify the case.

Store state for each item separately in RecyclerView

RecyclerView OnClick doesn't work properly. It has to change state to true or false. When I click on the first item it stores true and changes the text. But when I click on other item it changes the state to false because the first item set true, so the text doesn't change. How to store the states for each item separately?
boolean isChange = false;
#Override
public void onBindViewHolder(#NonNull final WindowViewHolder holder, int position) {
Window window = windowList.get(position);
holder.textViewTitle.setText(window.getTitle());
holder.textViewChecked.setText(window.getCheck());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(window.getImage()));
////////////////////////////////////////////////
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isChange){
holder.parentLayout.setBackgroundColor(Color.parseColor("#66BB6A"));
holder.textViewChecked.setText("True");
isChange = true;
}
else {
holder.parentLayout.setBackgroundColor(Color.parseColor("#EEEEEE"));
holder.textViewChecked.setText("False");
isChange = false;
}
//Toast.makeText(mCtx, "Clicked", Toast.LENGTH_SHORT).show();
}
});
//////////////////////////////////////
}
I hope you have a setCheck() method for your Window object where you store the checked state. The isChange variable you use is not item specific so it keeps the value of the previous checked item.
From what I understand by your code you should do this:
#Override
public void onBindViewHolder(#NonNull final WindowViewHolder holder, int position) {
Window window = windowList.get(position);
holder.textViewTitle.setText(window.getTitle());
holder.textViewChecked.setText(window.getCheck());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(window.getImage()));
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (window.getCheck().toString.equals("False")) {
window.setCheck("True");
holder.parentLayout.setBackgroundColor(Color.parseColor("#66BB6A"));
holder.textViewChecked.setText("True");
} else {
window.setCheck("False");
holder.parentLayout.setBackgroundColor(Color.parseColor("#EEEEEE"));
holder.textViewChecked.setText("False");
}
}
});
}
Why not to use Map?
I see you have some Window model. So you can create a map in you adapter and store a boolean value for each Window key:
private Map<Window, Boolean> map = new HashMap<>();
And then get value for the current value:
#Override
public void onBindViewHolder(#NonNull final WindowViewHolder holder, int position) {
Window window = windowList.get(position);
holder.textViewTitle.setText(window.getTitle());
holder.textViewChecked.setText(window.getCheck());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(window.getImage()));
////////////////////////////////////////////////
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean isChange = map.get(window);
if (!isChange){
holder.parentLayout.setBackgroundColor(Color.parseColor("#66BB6A"));
holder.textViewChecked.setText("True");
map.put(window, true);
}
else {
holder.parentLayout.setBackgroundColor(Color.parseColor("#EEEEEE"));
holder.textViewChecked.setText("False");
map.put(window, false);
}
//Toast.makeText(mCtx, "Clicked", Toast.LENGTH_SHORT).show();
}
});
//////////////////////////////////////
}

How can I have scrolling to last page working properly in a paginated scroll in android ListView

Attention! This question is not about dynamic loading of items into a very long ListView.
This is about adding PageUP and PageDown buttons to a ListView so that user can touch the button and scroll ListView page by page. Page means all fully and partially visible items on the screen.
I have partially implemented this in the following code, but my problem is that when I have lets say 10 items of approximately same height in the listview and 7 of them fit into the first page, then when I press PgDown button, user expects that item 8 to be on top of the screen (next page), but because there are only 10 items, ListView scrolls to the bottom of the list and because there is no extra scroll space I have item number 4 on top.
What is the best solution in this situation?
Should I add one item to the end of the list which will make the last page the height of the screen or there are any better options?
Here is my code:
public class cPaginatedListViewHelper {
Activity m_parentActivity;
private ListView mList;
//controls
private LinearLayout m_PagingLL;
//buttons
private ImageButton m_btnPrevPage;
private ImageButton m_btnNextPage;
private ImageButton m_btnExitPaginatedMode;
public cPaginatedListViewHelper(ListActivity mParent) {
this.m_parentActivity = mParent;
m_btnPrevPage=(ImageButton) mParent.findViewById(R.id.btnPrevPage);
m_btnNextPage=(ImageButton) mParent.findViewById(R.id.btnNextPage);
m_btnExitPaginatedMode =(ImageButton) mParent.findViewById(R.id.btnClosePage);
if(m_btnPrevPage!=null) {
m_btnPrevPage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showSiblingPage(-1);
}
});
m_btnPrevPage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mList.smoothScrollToPosition(0);
return true;
}
}
);
}
if(m_btnNextPage!=null) {
m_btnNextPage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showSiblingPage(1);
}
});
m_btnNextPage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
mList.smoothScrollToPosition(mList.getCount());
return true;
}
}
);
}
m_btnExitPaginatedMode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setEnabled(false);
m_PagingLL.setVisibility(View.GONE);
}
});
mList=mParent.getListView();
m_PagingLL = (LinearLayout) mParent.findViewById(R.id.pageControls);
}
public void updateControlsVisibility()
{
ViewTreeObserver observer = mList.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (willMyListScroll()) {
boolean psm = isEnabled();
//enable or disable
m_PagingLL.setVisibility( psm ? View.VISIBLE : View.GONE);
((View)mList).setVerticalScrollbarPosition(psm ? View.SCROLLBAR_POSITION_LEFT: View.SCROLLBAR_POSITION_RIGHT);
}
else
{
m_PagingLL.setVisibility(View.GONE);
((View)mList).setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
}
}
});
}
private boolean willMyListScroll() {
try {
int pos = mList.getLastVisiblePosition();
if (mList.getChildAt(pos).getBottom() > mList.getHeight()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private void showSiblingPage(int shift)
{
if(mList!=null) {
int iScrollPageHeight = mList.getHeight();
mList.scrollListBy(iScrollPageHeight * shift);
}
}
public void setEnabled(boolean psm) {
MyApp.Pref.edit().putBoolean("PSModeEnabled", psm).commit();
}
public boolean isEnabled(){
return MyApp.Pref.getBoolean("PSModeEnabled", false);
}
public void pagedScrollEnableDisable() {
boolean pagingEnabled = isEnabled();
pagingEnabled=!pagingEnabled;
setEnabled(pagingEnabled);
m_PagingLL.setVisibility( pagingEnabled ? View.VISIBLE : View.GONE);
updateControlsVisibility();
}
}
I finished up with using ListView's footer with variable height as shown in the following code:
LayoutInflater inflater = m_parentActivity.getLayoutInflater();
m_footerView = inflater.inflate(R.layout.listview_paged_overscroll, mList, false );
ViewGroup.LayoutParams lp =m_footerView.getLayoutParams();
if(m_tvPageNum!=null) recalcPagination();
if(lp!=null) lp.height = m_extraScrollFooterHeight;
int iFooters = mList.getFooterViewsCount();
if(iFooters==0) mList.addFooterView(m_footerView);

Sliding menu in android,misbehaviour

I am using Sliding menu from library jfeinstein, i have two sliding menu 'menuLeft' 'menuRight' in my activity one from left side and one from right,i have toggle buttons for respective sliding menu,how ever if menuLeft is open and if i slide from right to left in order to close menuLeft ,menuRiht also gets opened,what can be the solution to avoid this misbehaviour
here's my activity which contains SlidingMenu's
public class ChatListActivity extends SherlockActivity {
private SlidingMenu menuLeft;
private SlidingMenu menuRight;
private Button btnSliderLeftToggle;
private Button btnSliderRightToggle;
private ListView lvSliderLeft;
private ListView lvSliderRight;
private int width;
private int height;
private DBContacts db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.chatlist_layout);
db = new DBContacts(this);
WindowManager wmanager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = wmanager.getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
menuLeft = new SlidingMenu(this);
menuRight = new SlidingMenu(this);
initLeftSlider();
initRightSlider();
btnSliderLeftToggle = (Button) findViewById(R.id.mnuSlidingleftToggle);
btnSliderLeftToggle.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
ChatListActivity.this.menuLeft.toggle();
}
});
btnSliderRightToggle = (Button) findViewById(R.id.mnuSlidingRightToggle);
btnSliderRightToggle.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
ChatListActivity.this.menuRight.toggle();
}
});
menuLeft.setOnOpenedListener(new OnOpenedListener()
{
#Override
public void onOpened()
{
lvSliderLeft = (ListView) findViewById(R.id.lvSlidingmenuLeft);
MySLidingMenuLeftAdapter adapter = new MySLidingMenuLeftAdapter(ChatListActivity.this,
R.layout.crow_listview_lvslidingleft_chatlist);
lvSliderLeft.setAdapter(adapter);
}
});
menuRight.setOnOpenedListener(new OnOpenedListener()
{
#Override
public void onOpened()
{
lvSliderRight = (ListView) findViewById(R.id.lvSlidingmenuRight);
String column[] = new String[] { DBContacts.USERNAME};
int[] viewId = { R.id.txtContactName};
Cursor dataBaseCursor = db.getAllContacts();
MySLidingMenuRightAdapter customContactListAdapter = new MySLidingMenuRightAdapter(
ChatListActivity.this, R.layout.crow_lvslidingmenu_right_chatlist, dataBaseCursor, column,
viewId, 0);
lvSliderRight.setAdapter(customContactListAdapter);
}
});
}
private void initRightSlider()
{
menuRight.setMode(SlidingMenu.RIGHT);
menuRight.setBehindOffsetRes(R.dimen.slidingmenu_offset);
menuRight.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
menuRight.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
menuRight.setMenu(R.layout.sliding_menu_chatlist_right);
menuRight.setFadeDegree(0.35f);
}
private void initLeftSlider()
{
menuLeft.setMode(SlidingMenu.LEFT);
menuLeft.setBehindOffsetRes(R.dimen.slidingmenu_offset);
menuLeft.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
menuLeft.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
menuLeft.setMenu(R.layout.sliding_menu_chatlist_left);
menuLeft.setFadeDegree(0.35f);
}
#Override
public void onBackPressed()
{
super.onBackPressed();
System.exit(0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("Refresh");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
new SendNativeContacts(this).execute();
return true;
}
}
I have never faced this issue when i used both Left and Right SlidingMenu but for your problem you can have look at SlidingMenu Issues and you can try this solution for your problem. It may help you.
EDIT :
try this
You will need a patch which calls onOpened and onClosed methods for right menu it may have been included in latest code. Write logs to check method calls.
slidingMenuLeft.setOnOpenedListener(new OnOpenedListener() {
#Override
public void onOpened(int pos) {
slidingMenuRight.setSlidingEnabled(false);
}
});
slidingMenuLeft.setOnClosedListener(new OnClosedListener() {
#Override
public void onClosed() {
slidingMenuRight.setSlidingEnabled(true);
}
});
slidingMenuRight.setOnOpenedListener(new OnOpenedListener() {
#Override
public void onOpened(int pos) {
slidingMenuLeft.setSlidingEnabled(false);
}
});
slidingMenuRight.setOnClosedListener(new OnClosedListener() {
#Override
public void onClosed() {
slidingMenuLeft.setSlidingEnabled(true);
}
});

Deleting last item from spinner deletes the entire list

I am trying to use a spinner control that will enable the user to delete any list element.
I have an 'add' button to add elements to the list, and a 'delete' button that removes the currently-displayed item from the list.
It works as expected except when the user deletes the last item in the list. At that point, all of the list's items are deleted.
My code is as follows:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// grab our UI elements so we can manipulate them (for the Spinner)
// or add listeners to them (in the case of the buttons)
m_myDynamicSpinner = (Spinner)findViewById(R.id.dynamicSpinner);
m_addItemText = (EditText)findViewById(R.id.newSpinnerItemText);
Button addButton = (Button)findViewById(R.id.AddBtn);
Button clearButton = (Button)findViewById(R.id.ClearBtn);
// create an arrayAdapter an assign it to the spinner
m_adapterForSpinner = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
((ArrayAdapter)m_adapterForSpinner).setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
m_myDynamicSpinner.setAdapter(m_adapterForSpinner);
// add listener for addButton
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
addNewSpinnerItem();
}
});
clearButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
clearSpinnerItems();
}
});
}
// add listener for addButton
private void addNewSpinnerItem() {
if (m_addItemText.getText().length() == 0) {
Toast.makeText(getApplicationContext(), "The textView is empty", Toast.LENGTH_LONG).show();
} else {
CharSequence textHolder = "" + m_addItemText.getText();
((ArrayAdapter) m_adapterForSpinner).add(textHolder);
}
m_addItemText.setText("");
}
private void clearSpinnerItems() {
m_myDynamicSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
Object t = m_adapterForSpinner.getItem(pos);
((ArrayAdapter) m_adapterForSpinner).remove((CharSequence) t);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO
}
});
}
Does anyone have any ideas or suggestions on how to make this work?
The problem with your code is that the deletion is inside the onItemSelected callback, which gets called every time you are deleting an entry, thus deleting recursively until you effectively do not have any more entries to select. If you add a log inside that method:
Log.d("Spinner", "Count: " + m_adapterForSpinner.getCount());
you will see what I mean. I'm sure you can come up with more elegant code, but a quick and dirty hack is to set up a boolean flag to stop the recursion after the first deletion. See the snippet below and add the commented lines to your own code:
public class SpinnerTest extends Activity {
Spinner m_myDynamicSpinner;
EditText m_addItemText;
ArrayAdapter m_adapterForSpinner;
public static boolean cleared = false; // <--- set up a static boolean here
#Override
public void onCreate(Bundle savedInstanceState) {
// all your code unchanged
clearButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
cleared=false; // <--- nope, we did not clear the value yet
clearSpinnerItems();
}
});
}
// code unchanged
private void clearSpinnerItems() {
m_myDynamicSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
Object t = m_adapterForSpinner.getItem(pos);
Log.d("Spinner", "Count: " + m_adapterForSpinner.getCount());
if (!cleared) // <--- did I do it already?
((ArrayAdapter) m_adapterForSpinner).remove((CharSequence) t);
Log.d("Spinner", "Count: " + m_adapterForSpinner.getCount());
cleared=true; // I did it!
}
// code unchanged
i cann't understand your question.any way you can get the position of the selected item by using getSelectedItemPosition() method.

Categories

Resources