Sorting a Recyclerview list dynamically - android

I have a recyclerview list that is a check list. I want it to be sorted based on date and if the checkbox is checked or not. So if the user is on the main screen he/she should see a sorted list based on date and if he/she clicks a checkbox, I want that item to go the bottom of the list.
I wrote a compareTo method in the model class:
public int compareTo(BucketItem o) {
if (this.isChecked && !o.isChecked){
return -1;
}else if(!this.isChecked && o.isChecked){
return 1;
}else if (this.isChecked && o.isChecked){
return 0;
}else{
return getDate().compareTo(o.getDate());
}
}
The layout looks for one item looks like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:weightSum="1">
<!--<TextView-->
<!--android:id="#+id/contact_name"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_weight="1"-->
<!--/>-->
<RelativeLayout
android:layout_height="52dp"
android:layout_width="wrap_content"
android:id="#+id/RelativeLayout1"
android:orientation="vertical"
android:layout_marginBottom="16dp"
android:layout_weight="0.95">
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_centerVertical="true"
android:clickable="true"
android:onClick="itemClicked"
/>
<TextView
android:id="#+id/bucket_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/checkBox1"
android:layout_centerVertical="true"
android:text="TextView"
android:clickable="true"
android:onClick="editItem"/>
<TextView
android:text="TextView"
android:id="#+id/bucket_des"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="#+id/bucket_name"
android:layout_toEndOf="#+id/checkBox1" />
</RelativeLayout>
</LinearLayout>
My main question is where do I put the Collections.sort(list) so that it gets called every time a new item gets added to the list or a checkbox gets checked?

Create a method in your Adapter class and put Collections.sort(list) followed by notifyDataSetChanged in that class.
void update(){
Collections.sort(list);
notifyDataSetChanged();
}
Now call this method whenever any new item is added or checkbox is checked/un-checked.
CheckBox checkBox1;
checkBox1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
adapter.update();
}
});

I think you don't need to think about sorting the recycler view, instead you should sort the dataset with your required event and notify the recycler view by calling yourAdapter.notifyDataSetChanged()

Related

Neither setOnItemSelectedListener nor setOnClickListener works for GridView

The GridView is the following:
<GridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="0dp"
android:horizontalSpacing="0dp"
android:numColumns="2"
android:stretchMode="columnWidth"
android:verticalSpacing="0dp"
android:fadeScrollbars="false"
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="afterDescendants"/>
The Java code is the following:
gridview = (GridView) findViewById(R.id.gridview);
gridview.setNumColumns(iColumnCount);
gridview.setAdapter(dta);
gridview.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int iPosition, long l) {
utility.logd("gridview", "selected item position:" + iPosition);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
utility.logd("gridview", "nothing selected.");
}
});
gridview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
utility.logd("gridview", "item clicked");
}
});
Only onNothingSelected() is called once after the apps starts. None of the other listeners is called when the focus on the GridView is changed with a remote control, or any item is clicked.
Could anyone offer a tip on how to make the listeners work?
Everything else of the GirdView works as expected.
Edit: The following is the layout for each grid cell:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:layout_gravity="center"
android:id="#+id/biyee_relativeLayoutRoot">
<ImageButton
android:id="#+id/imageButton"
android:background="#drawable/button_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="snapshot"
android:layout_gravity="center"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:layout_margin="0dp"
android:padding="10dp"
android:src="#drawable/ic_launcher"
android:onClick="onClick_imageButton"/>
<LinearLayout
android:id="#+id/linearLayoutCaption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black_overlay"
android:orientation="vertical"
android:layout_margin="10dp"
android:padding="5dp">
<TextView
android:id="#+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/textViewModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Model"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView
android:id="#+id/textViewTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Time"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<TextView
android:id="#+id/textViewPosition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="n"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_margin="15dp"/>
</FrameLayout>
Edit (2):
Per the tip of Daniel Nugent, I removed the ImageButton from the custom item view layout for the purpose of testing, and OnItemSelectedListener started working perfectly. Therefore the culprit is ImageButton. It seems any clickable object would ruin OnItemSelectedListener.
Edit (3): For the sake of testing, I used the following layout for the custom item view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="300dp"
android:orientation="vertical"
android:background="#color/red">
</LinearLayout>
OnItemSelectedListener works perfectly, but OnClickListener and OnItemClickListener are never called no matter whether I use a mouse or remote control to click an item.
Try using OnItemClickListener instead of onItemSelectedListener
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
//Your Logic here
}
);
onItemSelectedListener will do the job if you implements some kind of selection like arrows or some other thing.
From developer.android.com
Callback method to be invoked when an item in this view has been
selected. This callback is invoked only when the newly selected
position is different from the previously selected position or if
there was no selected item.
Impelmenters can call getItemAtPosition(position) if they need to
access the data associated with the selected item.

ListView onItemClick not called

I have a ListView with a custom adapter and list items containing TextView(s) only. The list items have an OnItemClick method set in the onCreate callback method.
templatesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(DEBUG_TAG, "templatesListView onClick()");
//item is selected from the cursor to get necessary data
Log.d(DEBUG_TAG, "ListView count: " + templatesListView.getCount());
Log.d(DEBUG_TAG, "messagesCursor count: " + messagesCursor.getCount());
if (position >= messagesCursor.getCount()) {
Log.d(DEBUG_TAG, "Unable to access element " + position + ", it does not exist in the messagesCursor. Cursor count: " + messagesCursor.getCount());
}
messagesCursor.moveToPosition(position);
final String selectedItemName = messagesCursor.getString(1);
AlertDialog.Builder builder = new AlertDialog.Builder(SendMessageActivity.this);
builder.setTitle(selectedItemName).setMessage("Do you want to use template: "+selectedItemName+"?");
//Use template onClick
builder.setPositiveButton("Use", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int x) {
messageEditText.setText(selectedItemName);
}
});
//Cancel onClick
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int x) {
}
});
builder.show();
}
});
The ListView in the activity layout file is defined as:
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/templatesListView"
android:layout_alignParentRight="true"
android:clickable="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/sendButton" />
The list item is defined in a separate layout file as:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/name_textView" />
The onClick method is called correctly when I run the app on Android 4.4.4, but when I run it on Android 5.1.1 it is not called at all.
The list item layout has been also created for v21+ separately, please find the code below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Medium Text"
android:id="#+id/name_textView"
android:singleLine="true"
android:textColor="#color/foreground_material_light"
android:theme="#android:style/Widget.Material.Light.Button.Borderless" />
Do you guys know what should I change to make it work on API level 21+ ? Is that a matter of the xml file only (attributes?) or should I change the implementation? Cheers!
Just remove this,
android:clickable="true"
from your ListView. It is actually blocking the clicks from getting transferred to the individual rows.
SOLVED: I think the additional layout file was confusing for the application. It was named exactly the same as the original one, but with (v21) added at the end of it. After removing the second file it works fine.
Looking at this closely related problem and the selected answer, I think you should make some changes to your code.
Seeing that you have the LinearLayout which has a ListView as a child view - and this ListView has the LinearLayout as a child, which in turn has TextView as a child? In this case, perhaps the child views of your ListView should have the onClickListener. This means setting the following attributes to your name_textView:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:focusableInTouchMode="false"
android:clickable="false"
android:focusable="false"
android:id="#+id/name_textView" />
Then keep the templatesListView as :
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/templatesListView"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/sendButton" />
And finally, change your list-item linear layout as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:weightSum="1">
Give it a try and let me know if this helps.

how to overlap a layout with image view and text over the other layout as a stack/pile

I am in a weird situation in my existing project. In my project i want to inflate one layout over the other as a stack dynamically. At present in my project i managed to show the layouts one below the other vertically by appending them, this approach has been chosen by me because even though i am trying to show it as stack only one image is appearing at the front during runtime instead of a bunch. In order to understand my problem please go through the following image links and code
desired result
acquired_result_when_tried_to_acheive_desired_result
approached way
Parent layout:
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/imagegallery"
android:orientation="vertical"></LinearLayout>
child layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="#+id/relativeImage"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_below="#+id/rl1"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="15dp" >
<RelativeLayout
android:id="#+id/parent"
android:layout_width="wrap_content"
android:layout_height="250dp"
android:orientation="vertical" >
<Button
android:id="#+id/left1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="#drawable/close" />
<Button
android:id="#+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="#drawable/right" />
<ImageView
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:adjustViewBounds="true"
android:background="#drawable/deelpizza"
android:paddingBottom="15dp"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:scaleType="fitCenter" />
<RelativeLayout
android:id="#+id/left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/image"
android:background="#drawable/text_bg" >
<ImageView
android:id="#+id/imageprew"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
android:background="#drawable/icon_3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/imageprew"
android:text="This is an exclusive Deel good for today only clime this deel before its close!"
android:textColor="#FFFFFF" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="15dp"
android:layout_below="#+id/imageprew" >
</RelativeLayout>
</RelativeLayout>
<!--
<Button
android:id="#+id/left"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_alignParentLeft="true"
android:background="#drawable/text_bg"
android:layout_alignTop="#+id/image"
/>
-->
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/relativeDetails"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/relativeImage"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#drawable/rectangle" >
<TextView
android:id="#+id/locationText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/descText"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:text="woodfire pizza, Los Gatos CA\nLimited time offer, redeemable today only."
android:textColor="#000000" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_below="#+id/locationText" />
<TextView
android:id="#+id/descText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:text="1 large, 2 topping pizza"
android:textColor="#000000"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:text="$15"
android:textColor="#FF0000"
android:textSize="25dp" />
</RelativeLayout>
JavaCode:
private void addImagesToThegallery() {
LinearLayout imageGallery = (LinearLayout)findViewById(R.id.imagegallery);
//imageGallery.setPadding(0, 0, 0, 30);
LayoutInflater layoutInfralte=(LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
List views=new ArrayList();
View view;
for(int j=0; j<=5; j++)
{
view=layoutInfralte.inflate(R.layout.newdeels, null);
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
views.add(view);
}
for(int i = 0; i<views.size(); i++)
{
imageGallery.addView((View) views.get(i));
}
Please go through my code and let me know where am i going wrong and let me know if i am unclear anywhere
Change the margin top to make views come down a bit
for(int j=0; j<=5; j++)
{
view=layoutInfralte.inflate(R.layout.newdeels, null);
LinearLayout.LayoutParams lp=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
lp.setMargins(left,5*j, right, bottom);
view.setLayoutParams(lp);
views.add(view);
}
for(int i = 0; i<views.size(); i++)
{
imageGallery.addView((View) views.get(i));
}
Checkout following
Github : Material Recent Layout
Usage
RecentsList recents = (RecentsList) findViewById(R.id.recents);
recents.setAdapter(new RecentsAdapter() {
#Override
public String getTitle(int position) {
return "Item "+position;
}
#Override
public View getView(int position) {
ImageView iv =new ImageView(RecentsActivity.this);
iv.setImageResource(R.drawable.mazda);
iv.setBackgroundColor(0xffffffff);
return iv;
}
#Override
public Drawable getIcon(int position) {
return getResources().getDrawable(R.mipmap.ic_launcher);
}
#Override
public int getHeaderColor(int position) {
return colors[random.nextInt(colors.length)];
}
#Override
public int getCount() {
return 10;
}
}
Note
You need to modify as per your requirement.
Try FrameLayout in your parent layout. Set different margins in child views to achive an effect of stack.
Child views are drawn in a stack, with the most recently added child on top
check out : github.com/kikoso/Swipeable-Cards
As per your response :
hi thank you for your response ur response actually worked. But now i am dealing with another situation where-in i would like to update details based on swipe for eg: if a card is swiped right it should be gestured as like where as if a card is swiped left it should be gestured as dislike so how to actually code these swipe gestures can you please help me out
#ashwin for that you should have a like and dislike drawable or a custom view.
card.setOnCardDimissedListener(new CardModel.OnCardDismissedListener() {
#Override
public void onLike() {
Log.d("Swipeable Card", "I liked it");
}
#Override
public void onDislike() {
Log.d("Swipeable Card", "I did not liked it");
}
});
Use above snippet to show or hide the view of like or dislike in respective methods that is onLike() and onDislike().
Edit 1:
I figured out the problem what you are facing, If you are simply implementing the Sample Code. Then it clearly shows that CardContainer has SimpleCardStackAdapter as adapter and CardModel are added to it using new operator. Except the last element of CardModel that is added separately and cardModel Listener is applied on last element only. If you want to apply it on all elements. Then you should have to add the elements to SimpleCardStackAdapter by ArrayList of CardModel.

keyboard reset radiogroup value

I have a custom ListView with a radiogroup in each row.
When I change the checked radio button, I call a dialog with some edittext fields (using the onCheckedChanged() method). But, when i focused an edittext to write something, I lose all the checked radiobuttons which are covered by keyboard, and the group returns to the default option selected.
can someone help me?
List adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ContractItemHolder cih = new ContractItemHolder();
if (row == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(R.layout.row_proposals_item, parent, false);
cih.setTvItemTitle((TextView)row.findViewById(R.id.textViewItemTitle));
cih.setRgItemStatus((RadioGroup)row.findViewById(R.id.radioGroupStatus));
row.setTag(cih);
}else {
cih=(ContractItemHolder)row.getTag();
}
final ContractItem ci = list.get(position);
cih.getRgItemStatus().setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
groupSel = group;
int selected = group.getCheckedRadioButtonId();
Dialog d;
switch (selected) {
case R.id.radioAccepted:
d = createDialog(context, ACCEPTED_CODE, ci, selected);
d.show();
break;
case R.id.radioRefused:
d = createDialog(context, REFUSED_CODE, ci, selected);
d.show();
break;
default:
break;
}
}
});
cih.getTvItemTitle().setText(ci.getDescItem());
return row;
}
List item layout (the row..)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:gravity="center">
<TextView
android:id="#+id/textViewItemTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Large Text"
android:layout_weight="3"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<RadioGroup
android:id="#+id/radioGroupStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1"
android:showDividers="middle">
<RadioButton
android:id="#+id/radioNull"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Non Proposto"
android:checked="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<RadioButton
android:id="#+id/radioPending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="In trattativa"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Blue"/>
<RadioButton
android:id="#+id/radioAccepted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Accettato"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Green"/>
<RadioButton
android:id="#+id/radioRefused"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rifiutato"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Red"/>
</RadioGroup>
</LinearLayout>
Dialog impl
private Dialog createDialog(Context context, final int code, ContractItem item,final int selected){ //type: refused, accepted
d = new Dialog(context);
d.setTitle(item.getDescItem());
d.setContentView(R.layout.layout_dialog_prop);
d.getWindow().setLayout(900, LayoutParams.WRAP_CONTENT);
d.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Button btnOK = (Button)d.findViewById(R.id.buttonPropOK);
Button btnCancel = (Button)d.findViewById(R.id.buttonPropCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.dismiss();
}
});
btnOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.dismiss();
}
});
return d;
}
Dialog layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="50dp" >
<EditText
android:id="#+id/editTextDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="Sconto proposto"
android:inputType="number"
android:textAppearance="?android:attr/textAppearanceLarge" >
<requestFocus />
</EditText>
<Spinner
android:id="#+id/spinnerScuse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="gone" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:ems="10"
android:gravity="top"
android:hint="Note"
android:inputType="textMultiLine"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<View
android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="30dp"
android:background="#android:color/holo_blue_light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/buttonPropCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Annulla"
android:textColor="#android:color/holo_blue_light" />
<View
android:id="#+id/view1"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light" />
<Button
android:id="#+id/buttonPropOK"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Ok"
android:textColor="#android:color/holo_blue_light" />
</LinearLayout>
</LinearLayout>
You are partially aware of the list-item view recycling process.
The ListView component doesn't generate view for each item in the list. So, there won't be 15 of them in your case. There will be just as many as can fit on the screen. When you scroll the list, the old items, which are no longer visible, are recycled. The getView is then called with convertView != null and the adapter is giving you an opportunity to update this recycled item view. This is done for performance reasons - just imagine an adapter having 10000 items (not a rare thing in commercial applications). Should it create all 10000 list item views? Imagine the performance you would have while scrolling such a list...
In your getView() code, you update an item view only partially - you always set item title in this line:
cih.getTvItemTitle().setText(ci.getDescItem());
When an fresh item view is created (i.e. the convertView == null) the radio group has a default selection, which may be fine in your case.
However, when the item view is recycled (i.e. the convertView != null), then you:
set a change listener in this line:
cih.getRgItemStatus().setOnCheckedChangeListener(...);
set item title:
cih.getTvItemTitle().setText(ci.getDescItem());
But you never set the checked radio group item. That means, it will have a value which was last set for this instance of item view - not for that position. You should store that information - probably in ContractItem, update it when the radio group item is selected and finally - retrieve it when convertView != null and set selected item of the radio group to the correct value.
You probably see this defect when you open up a dialog - the visible area of a ListView becomes smaller as the soft keyboard opens. This causes the ListView to remove unnecessary (technically: no longer visible) item views. When you hide the soft keyboard, the ListView area becomes larger again thus causing it to create missing item views. Unfortunately, you don't save and restore the last selected item of the radio group and so, after creation the newly visible items have the default item selected in the radio group.

Listview multiple choice

I use a listview with multiple choice and I override the search method inside. I have a problem with the items in that during scrolling the position of items changed. The problem comes from the layout, I think, because when the layout includes only the listview, it works correctly. But, when I use the layout below, the positions of the items checked during scrolling get changed.
Can anyone help with that please?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/button1" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Button" />
<ListView
android:id="#+id/MyListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/editText1" />
</RelativeLayout>
You need to set up an object in your adapter to keep track of the state of the checkboxes. You haven't shown your adapter code so I'll just pull an example from some of my code (this is using a cursor, it can be adapted to an ArrayAdapter)
In the custom adapter set an array:
private Cursor c;
public static int[] checked;
In your constructor set your cursor to the local var and call a method:
CursorAdapter_EditText.c = c;
initializeChecked();
The method (using 0 = not checked):
public static void initializeChecked() {
checked = new int[c.getCount()];
int i = 0;
while (i < c.getCount()) {
checked[i] = 0;
i++;
}
}
In your getView use the array to set the checkbox state:
checkBox = (CheckBox) view.findViewById(R.id.CheckBox);
if (checked(position) == 0) {
checkBox.setChecked(false);
} else {
checkBox.setChecked(true);
}
You'll need to add code in checkBox.setOnCheckedChangeListener also to change the state in the array when you change the state of the checkbox.

Categories

Resources