listview refresh in android databinding - android

I am working with one of application using android MVVM architecture with databinding concepts.
The problem is when i am updating the textview of the xml the entire view gets updated.so listview gets refreshed and scroll to top position.i want to restrict the listview when onItem click event occurs.
Following xml contains listview.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="kenoservicesVM"
type="com.naushad.kenocustomer.landing.KenoServicesVM" />
<variable
name="kenoservice"
type="com.naushad.kenocustomer.landing.KenoService" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/nliveo_transparent"
android:paddingEnd="20sp"
android:paddingStart="20sp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:text="Total"
android:textColor="#color/white" />
<ScrollView
android:id="#+id/SCROLLER_ID"
android:layout_width="fill_parent"
android:layout_height="160sp"
android:layout_margin="0sp"
android:background="#color/nliveo_transparent"
android:fillViewport="true"
android:scrollbars="none">
<ListView
android:id="#+id/lstServices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onItemClick="#{kenoservicesVM::onItemClick}"
bind:items="#{kenoservicesVM.mList}">
</ListView>
<!--android:onItemClick="#{kenoservicesVM::onItemClick}"-->
</ScrollView>
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:text="Total"
android:textColor="#color/white" />
<TextView
android:id="#+id/totalCharges"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:textColor="#color/white" />
<!--android:text="#{kenoservicesVM.totalPrice ?? #string/_0_aed}"-->
</LinearLayout>
<RelativeLayout
android:id="#+id/your_btn_id"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/bgNext"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginBottom="5dip"
android:layout_marginTop="15dip"
android:alpha="0.5"
android:src="#drawable/blue_round_light_bg" />
<Button
android:id="#+id/btn_add_card"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_marginBottom="5dip"
android:layout_marginTop="15dip"
android:background="#drawable/blue_next_bg" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>
</layout>
Following viewmodel class indicates the viewmodel which i have used in xml.
public class KenoServicesVM extends BaseObservable {
public ObservableArrayList<KenoService> mList = new ObservableArrayList<>();
private Context mContext;
#NonNull
private String mTotalPrice;
int selectedServiceCharges=0;
private int bar;
public ObservableField<String> price;
Handler handler;
public KenoServicesVM(List<KenoService> list, Context mContext) {
mList.addAll(list);
this.mContext = mContext;
}
#NonNull
public String getTotalPrice() {
return mTotalPrice;
}
public void setTotalPrice(#NonNull String totalPrice) {
this.mTotalPrice = totalPrice;
// notifyPropertyChanged(BR.kenoservicesVM);
// notifyPropertyChanged(BR.totalPrice);
notifyChange();
// notifyPropertyChanged(BR.kenoservicesVM);
}
#BindingAdapter("bind:items")
public static void bindList(ListView view, ObservableArrayList<KenoService> list) {
CustomListAdapter adapter = new CustomListAdapter(list);
view.setAdapter(adapter);
}
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
if(position == 0) return;
if(mList.get(position).getSelected())
mList.get(position).setSelected(false);
else
mList.get(position).setSelected(true);
for (int i=0 ;i<mList.size();i++){
KenoService keno = mList.get(i);
if(keno.getSelected())
selectedServiceCharges +=Integer.parseInt(keno.getKenoServiceCharge());
}
/*handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
price = new ObservableField<>(selectedServiceCharges +" AED");
}
});
}
};
new Thread(runnable).start();*/
setTotalPrice(selectedServiceCharges +" AED");
// dialogueServicesBinding.totalCharges.setText(selectedServiceCharges +" AED");
// mTotalPrice = selectedServiceCharges +" AED";
// ModuleManager.startActivity(ModuleManager.DISPATCH_MODULE, DispatchModule.STATE_FORGOTPASSWORD, (Activity) mContext);
}
}
I am new to android databinding concepts.Please help me to resolve this issue when i click on listview item and refreshing the view.Thanks in advance.

You need to use Bindable for your properties.
#NonNull
#Bindable
public String getTotalPrice() {
return mTotalPrice;
}
This will create the BR.totalPrice field and you'll be able to call
notifyPropertyChanged(BR.totalPrice);
and the text should update with it
android:text="#{kenoservicesVM.totalPrice ?? #string/_0_aed}"
Additionally #NonNull is a promise you might not be able to hold. Consider adding a default value.

Sorry I can't leave a comment due to reputation but I have bumped into one of the similar problem before, you can pass mList and position in your setTotalPrice methods and then called notifyItemChanged instead of notifyChange, this way it will update only the item at the specified position in your list
public void setTotalPrice(#NonNull String totalPrice, int position, ObservableArrayList<KenoService> mList, TextView totalCharges) {
this.mTotalPrice = totalPrice;
mList.notifyItemChanged(position);
totalCharges.setText(//whatever u need here);
totalCharges.invalidate();
}

Related

Ripple Effect in Android Recycler View is not working

I'm trying to add a ripple effect for the entire row (like we see in listview) in my Recycler View when the row is clicked.
I have tried
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
But still, I couldn't get the desired behavior. Even I have tried
android:foreground="?android:attr/selectableItemBackground"
But still no improvement
My listrow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<RadioButton
android:id="#+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/heading"
android:text="Title"
android:textSize="20dp"
android:paddingTop="5dp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_toLeftOf="#+id/subHeading"
android:id="#+id/size"
android:text="Sub Title"
android:paddingTop="3dp"
android:paddingLeft="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
And My layout with Recycler View
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<androidx.recyclerview.widget.RecyclerView
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingTop="#dimen/list_item_spacing_half"
android:paddingBottom="#dimen/list_item_spacing_half"
android:layout_alignParentTop="true"
tools:context=".ListFragment"
tools:listitem="#layout/listrow" />
<Button
android:id="#+id/Save"
android:layout_width="match_parent"
android:text="Save"
android:layout_below="#+id/list"
android:textAllCaps="false"
android:layout_height="wrap_content"/>
</RelativeLayout>
Here is my adapter source code
private class listAdapter extends RecyclerView.Adapter<ViewHolder> {
private final int mItemCount;
final ArrayList<String> mTitles;
final ArrayList<String> msTitles;
ArrayList<RadioButton> radioButtons=new ArrayList<>();
listAdapter(int itemCount, ArrayList<String> titles, ArrayList<String> sTitles) {
mItemCount = itemCount;
mtitles=titles;
msTitles=sTitles;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.sTitle.setTag(position);
holder.radioButton.setTag(position);
holder.title.setTag(position);
holder.title.setText(mTitles.get(position));
holder.sTitle.setText(msTitles.get(position));
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
ItemCheckChanged(v);
}
};
holder.radioButton.setOnClickListener(listener);
holder.sTitle.setOnClickListener(listener);
holder.title.setOnClickListener(listener);
if(radioButtons.size()==0){
holder.radioButton.setChecked(true);
selectedItem=0;
}
radioButtons.add(holder.radioButton);
}
#Override
public int getItemCount() {
return mItemCount;
}
void ItemCheckChanged(View v){
selectedItem=(int)v.getTag();
for(RadioButton radioButton:radioButtons){
radioButton.setChecked(false);
}
radioButtons.get(selectedItem).setChecked(true);
notifyDataSetChanged();
}
public int getSelectedIndex(){
return selectedItem;
}
}
NOTE: I'm using these all things in BottomSheetDialog may it be reason?
You should set background to views that have set a click listener.
If you want to set the listener to the whole row you need to call only:
holder.itemView.setOnclickListener() and remove rest of them.

RecyclerView not populating, likely a silly adapter problem

I used a working RecyclerView as a template for another, but I made some sort of mistake in its implementation and I can't find it. Here is the code that initializes the view:
mMessageThreadList = new ArrayList<>();
mRecyclerView = findViewById(R.id.chat_list_recycler_view);
private void initRecyclerView() {
Log.d(TAG, "initRecyclerView Called");
//Initializes and sets up adapter
mAdapter = new ChatListRecyclerViewAdapter(mThreadList);
mRecyclerView.setAdapter(mAdapter);
Query query = mThreadCollection;
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
switch (documentChange.getType()) {
case ADDED:
Thread thread = documentChange.getDocument().toObject(Thread.class);
Log.d(TAG, "Last Message: " + thread.getLastMessage().getMessage());
mThreadList.add(thread);
mAdapter.notifyDataSetChanged();
}
}
}
});
}
Note that the print log statement in the SnapshotListener does contain a value when printed so the information is returning from Firebase, it's just not displaying. Which makes me think my problem is with my Adapter/Viewholder:
public class ChatListRecyclerViewAdapter extends RecyclerView.Adapter<ChatListRecyclerViewAdapter.ChatListViewHolder> {
private List<Thread> threadList;
ChatListRecyclerViewAdapter(List<Thread> threadList) {
this.threadList = threadList;
}
#NonNull
#Override
public ChatListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_list_row, parent, false);
return new ChatListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ChatListViewHolder holder, int position) {
// This method fills fields with data for each list item
Log.d(TAG, "onBindViewholder called");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM hh:mm a");
final Thread thread = threadList.get(position);
char initial = thread.getPartnerName().charAt(0);
char uppercaseInitial = Character.toUpperCase(initial);
Log.d(TAG, thread.getLastMessage() + " " + thread.getPartnerID());
holder.partnerName.setText(thread.getPartnerName());
holder.authorInitial.setText(uppercaseInitial);
holder.lastMessageText.setText(thread.getLastMessage().getMessage());
holder.lastMessageTime.setText(simpleDateFormat.format(thread.getLastMessage().getTimestamp()));
}
#Override
public int getItemCount() {
return threadList.size();
}
//Viewholder stores the information about the layout and content of each list item, and serves as a template for each item of a RecyclerView
public class ChatListViewHolder extends RecyclerView.ViewHolder {
TextView partnerName;
TextView authorInitial;
TextView lastMessageText;
TextView lastMessageTime;
LinearLayout listTextHolder;
public ChatListViewHolder(View itemView) {
super(itemView);
partnerName = itemView.findViewById(R.id.partner_name);
authorInitial = itemView.findViewById(R.id.partner_initial);
lastMessageText = itemView.findViewById(R.id.last_message);
lastMessageTime = itemView.findViewById(R.id.last_message_time);
listTextHolder = itemView.findViewById(R.id.list_text_holder);
}
}
}
chat_list_row.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/single_thread_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="#color/colorPrimaryDark">
<TextView
android:id="#+id/partner_initial"
android:background="#drawable/chat_list_circle"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentStart="true"
android:gravity="center"
android:text="A"
android:textSize="36sp"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/last_message_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:padding="5dp"
android:fontFamily="#font/nunito_extralight"
android:text="#string/sample_time"
android:textColor="#android:color/darker_gray"
android:textSize="12sp"
android:typeface="normal" />
<LinearLayout
android:id="#+id/list_text_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/partner_initial"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:id="#+id/partner_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="5dp"
android:fontFamily="#font/nunito"
android:text="#string/sample_name"
android:textColor="#color/white"
android:textSize="14sp"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/last_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:fontFamily="#font/nunito_extralight"
android:gravity="start"
android:text="#string/sample_message"
android:textColor="#android:color/darker_gray"
android:textSize="12sp"
android:typeface="normal" />
</LinearLayout>
</RelativeLayout>
Edit: Layout of the Activity that RecyclerView appears in. I also edit above code to show where the variable is attached to the view:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/colorPrimaryDark"
android:paddingLeft="0dp"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="0dp"
android:paddingBottom="0dp"
tools:context="org.andrewedgar.theo.ChatListActivity">
<include
android:id="#+id/chat_list_toolbar"
layout="#layout/toolbar" />
<android.support.v7.widget.RecyclerView
android:id="#+id/chat_list_recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/chat_list_toolbar" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/new_check_in_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:src="#drawable/ic_person_pin_circle_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
Seems like you have missed to add layout manager of RecyclerView. Would you please add this and try again
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
Your recyclerview is not showing any data because the list in adapter is still empty. After fetching data from firebase you are adding to mThreadList, which is still with activity and not adapter. To update the list in adapter you can add a method in adapter class and pass the list to adapter and notifyDataseChanged there.
Activity:
//after firebase task...
mAdapter.updateData(mThreadList);
Adapter: add new method
void updateData(List<Thread> threadList){
this.threadList = threadList;
notifyDatasetChanged(); //notify adapter that new list is added
}

How to handle "ReadMore" Button click present in my List

BusinessForSaleActivity
public class BusinessForSaleActivity extends AppCompatActivity {
DatabaseReference databaseLinks;
ListView listViewBusinessForSale;
Button readMore;
ArrayList<BusinessForSale> list;
//CardView cardView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_business_for_sale);
listViewBusinessForSale = (ListView)findViewById(R.id.ListViewBusinessForSale);
list = new ArrayList<>();
databaseLinks = FirebaseDatabase.getInstance().getReference("BusinessList");
databaseLinks.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
list.clear();
try{
for(DataSnapshot businessSnapshot : dataSnapshot.getChildren()){
BusinessForSale b = businessSnapshot.getValue(BusinessForSale.class);
list.add(b);
}
}
catch (Exception ex){
Log.e("Error Descr:",ex.getMessage());
}
BusinessForSaleList adapter=new BusinessForSaleList(BusinessForSaleActivity.this,list);
listViewBusinessForSale.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(BusinessForSaleActivity.this,"Something is wrong",Toast.LENGTH_SHORT).show();
}
});
}
}
BusinessForSaleList================(Adapter class)============
public class BusinessForSaleList extends ArrayAdapter<BusinessForSale> {
private Activity context;
private List<BusinessForSale> businessForSaleList;
public BusinessForSaleList(Activity context,List<BusinessForSale> businessForSaleList){
//super(context,R.layout.list_layout,businessForSaleList);
super(context,R.layout.list,businessForSaleList);
this.context=context;
this.businessForSaleList=businessForSaleList;
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View listViewItem=inflater.inflate(R.layout.list,null,true);
ImageView imgBuiness=(ImageView)listViewItem.findViewById(R.id.imgViewBusiness);
TextView txtTitle = (TextView)listViewItem.findViewById(R.id.txtViewTitle);
TextView txtType = (TextView)listViewItem.findViewById(R.id.txtViewType);
TextView txtDescr = (TextView)listViewItem.findViewById(R.id.txtViewDescr);
Button btnReadMore = (Button)convertView.findViewById(R.id.buttonReadMore);
BusinessForSale businessForSale = businessForSaleList.get(position);
Picasso.get().load(businessForSale.getImage().toString()).into(imgBuiness);
txtTitle.setText(businessForSale.getBusiness_Title());
txtType.setText(businessForSale.getBusiness_Type());
txtDescr.setText(businessForSale.getDescription());
return listViewItem;
}
}
BusinessForSaleActivity.xml==============================================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BusinessForSaleActivity">
<ListView
android:id="#+id/ListViewBusinessForSale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:footerDividersEnabled="false"
/>
</RelativeLayout>
List.xml================================================================
[<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e0e0e0">
<android.support.v7.widget.CardView
android:id="#+id/cardBusinessForSale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:id="#+id/L1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imgViewBusiness"
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_margin="4dp"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/txtViewTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:layout_marginBottom="8dp"
android:textColor="#000"
android:textSize="18sp"/>
<TextView
android:id="#+id/txtViewType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#555" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="vertical">
<TextView
android:id="#+id/txtViewDescr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:maxLines="3"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<Button
android:id="#+id/buttonReadMore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/PrimaryFlatButton"
android:text="Read More" />
<Button
android:id="#+id/buttonAddToFvrt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/PrimaryFlatButton"
android:text="Add to Favorites" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>][1]
I want to redirect to new Activity on "ReadMore" button click. I am fetching firebase data into a listview using list.xml layout.
When you're using a list and need to handle click on an item or an element contained by it, the common way is to set a listener in the getView() method or onBind() method, depending on the adepter you're using.
In this case, in your "getView()" method, after referenced your button you need to set a listener on it that retrieve the position of the item that contains it and open the relative activity (or the unique activity setting up the correct value). You can do it by retrieving the parent position of its parent, but it's sounds so complicated.
The best and common way is to assign to the button a tag that is the position assigned to its parent by the getView() method in this way:
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View listViewItem=inflater.inflate(R.layout.list,null,true);
...
Button btnReadMore = (Button)convertView.findViewById(R.id.buttonReadMore);
btnReadMore.setTag(position + "");
}
After that, every button contains the position of the item in the list. Now, assign the listener to the button and retrieve the correct position:
btnReadMore.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view,....){
Button btnReadMore = (Button) view; //This cast is unless, it's here only for more understanding
String positionString = btnReadMore.getTag();
int position = Integer.parseInt(positionString);
BusinessForSale correctItem = BusinessForSaleList.get(position);
//here start activity you need.
}});
Hope this help! :D

Material design stepper control

Could someone give me an idea how to begin implementing vertical, non-linear stepper control described in the Android Material Design guide here:
http://www.google.com/design/spec/components/steppers.html
you can check this library , however this is still in development.
just extend the mobileStepperSimple class and implement the methods init,onFinished.
you can add the steppers as fragments by extending the stepperFragment and implement onNextButtonHandler to handle next button click.
check the demo for more usage.
any contributions and optimization will be helpful.
Well not exactly the same but as per my requirement, I developed custom VERTICAL STEPPER.
Below is the source code of whole demo.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"/>
</LinearLayout>
Single Item for List(Design your single item of your stepper in raw.xml file)
raw.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_upper_line"
android:layout_width="wrap_content"
android:layout_height="20dp"
app:srcCompat="#drawable/order_status_line" />
<ImageView
android:id="#+id/iv_circle"
android:layout_width="30dp"
android:layout_height="30dp"
app:srcCompat="#drawable/circle_o" />
<ImageView
android:id="#+id/iv_lower_line"
android:layout_width="wrap_content"
android:layout_height="20dp"
app:srcCompat="#drawable/order_status_line" />
</LinearLayout>
<LinearLayout
android:id="#+id/ly_status"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/tv_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="Order Rcived"
android:layout_gravity="left"
android:textSize="18sp"
android:textStyle="bold" />
<LinearLayout
android:id="#+id/ly_orderstatus_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|top"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageview"
android:layout_width="20dp"
android:layout_height="20dp"
app:srcCompat="#drawable/ic_restore_black" />
<TextView
android:id="#+id/tv_orderstatus_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|top"
android:text="8:30am,Jan 31,2018"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
orderStatusList();
}
private void orderStatusList() {
ArrayList<OrderStatusModel> arrayOfStatus =OrderStatusModel.getStoreDetail();
OrderStatusAdapter adapter = new OrderStatusAdapter(this, arrayOfStatus);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
Adapter Class
class OrderStatusAdapter extends ArrayAdapter<OrderStatusModel> {
Context context;
ArrayList<OrderStatusModel> order_status;
boolean isOn = false;
public OrderStatusAdapter(Contextcontext,ArrayList<OrderStatusModel>order_status{super(context, 0, order_status);
this.context = context;
this.order_status = order_status;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Check if an existing view is being reused, otherwise inflate the view if(convertView==null)convertView=LayoutInflater.from(getContext()).inflate(R.layout.raw,parent,false);
}
// Get the data item for this position
OrderStatusModel order_status_data = getItem(position);
// Lookup view for data population
ImageView iv_upper_line = (ImageView)
convertView.findViewById(R.id.iv_upper_line);
ImageView iv_lower_line =(ImageView)
convertView.findViewById(R.id.iv_lower_line);
final ImageView iv_circle = (ImageView) convertView.findViewById(R.id.iv_circle);
TextView tv_status = (TextView) convertView.findViewById(R.id.tv_status);
TextView tv_orderstatus_time =(TextView)
convertView.findViewById(R.id.tv_orderstatus_time);
LinearLayout ly_orderstatus_time = (LinearLayout)
convertView.findViewById(R.id.ly_orderstatus_time);
LinearLayout ly_status = (LinearLayout) convertView.findViewById(R.id.ly_status);
// Populate the data into the template view using the data object
tv_status.setText(order_status_data.getTv_status());
tv_orderstatus_time.setText(order_status_data.getTv_orderstatus_time());
if(position == 0){
iv_upper_line.setVisibility(View.INVISIBLE);
}
else if (position == order_status.size()-1){
iv_lower_line.setVisibility(View.INVISIBLE);
ly_orderstatus_time.setVisibility(View.GONE);
}
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
iv_circle.setBackgroundResource(R.drawable.bullseye);
Toast.makeText(context, "You Clicked at
item"position,Toast.LENGTH_SHORT).show();
}
});
// Return the completed view to render on screen
return convertView;
}
}
Model Class
private String tv_status;
private String tv_orderstatus_time;
public OrderStatusModel(String tv_status, String tv_orderstatus_time) {
this.tv_status = tv_status;
this.tv_orderstatus_time = tv_orderstatus_time;
}
public String getTv_status() {
return tv_status;
}
public void setTv_status(String tv_status) {
this.tv_status = tv_status;
}
public String getTv_orderstatus_time() {
return tv_orderstatus_time;
}
public void setTv_orderstatus_time(String tv_orderstatus_time) {
this.tv_orderstatus_time = tv_orderstatus_time;
}
public static ArrayList<OrderStatusModel> getStoreDetail() {
ArrayList<OrderStatusModel> status = new ArrayList<OrderStatusModel>();
status.add(new OrderStatusModel("Order Rcived", "8:30am,Jan 31,2018"));
status.add(new OrderStatusModel("On The Way", "10:30am,Jan 31,2018"));
status.add(new OrderStatusModel("Delivered", "aaaaaa"));
return status;
}
Because no Support Library solution exists (still) I have tried several of these libraries in a recent project. My favourite (for appearance, smoothness and functionality) was This Project by "ernestoyaquello". I also added some options to it on My Fork.
The only thing to note with this, is that it does not use an 'adapter' class but instead uses a callback interface.
Demo Screen from Git:

Issue inputting data in elements inside dynamic list

In the Android app I'm developing I'm loading a list of several items for the user to input some data; there's a checkbox and an EditText for each item, and the user can check the checkbox and type some notes regarding the item. This list is loaded dynamically from a local database, which in turn is populated from a remote database at a previous point. Now, the problem I'm having is that, whenever I focus on an EditText, after I lose focus on the element, the list seems to load again (elements which where unchecked/blank originally and had been checked/had text typed in them become unchecked/blank again, and those which were checked/had text initially go back to the original state). This only happens when I lose focus on the EditText; I can check and uncheck the checkboxes and they stay how I leave them (until I get and lose focus on an EditText). How can I avoid this so my elements retain the data?
I've tested the app in deviced with Android versions 3.2 and 4.2
Any help would be appreciated.
Here's the activity that loads the list:
public class PostventaPreentregaDetalleActivity extends Activity implements OnItemClickListener, OnItemSelectedListener {
private ArrayList<EncuestaPostventa> listaChequeoEncuesta;
private ArrayList<ConsumoBien> listaConsumoBien;
private ListView lvChequeoEncuesta;
private ListView lvConsumoBien;
private EncuestaPostventaAdapter adapter;
private ConsumoBienAdapter adapterConsumoBien;
public static DBProvider oDB;
#Override
public void onBackPressed() {
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.postventa_preentrega_detalle_activity_actions, menu);
return true;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
getActionBar().setDisplayHomeAsUpEnabled(true);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_postventa_preentrega_detalle);
listaChequeoEncuesta = new ArrayList<EncuestaPostventa>();
listaConsumoBien = new ArrayList<ConsumoBien>();
inicializarPestanas();
cargarDetalleNegocio();
listarChequeoEncuesta();
listarConsumoBien();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public void onItemClick(AdapterView<?> adapter, View view, int position,
long ID) {
}
public void cargarDetalleNegocio(){
Intent intent = getIntent();
TextView tvProyecto;
TextView tvCliente;
TextView tvRut;
TextView tvDireccion;
tvProyecto = (TextView) findViewById(R.id.tvProyecto);
tvRut = (TextView) findViewById(R.id.tvRut);
tvCliente = (TextView) findViewById(R.id.tvCliente);
tvDireccion = (TextView) findViewById(R.id.tvDireccion);
tvProyecto.setText(intent.getStringExtra("proyecto").trim());
tvRut.setText(intent.getStringExtra("rut").trim());
tvCliente.setText(intent.getStringExtra("cliente").trim());
tvDireccion.setText(intent.getStringExtra("direccion").trim());
}
public void inicializarPestanas(){
TabHost tabs = (TabHost)findViewById(android.R.id.tabhost);
tabs.setup();
TabHost.TabSpec spec = tabs.newTabSpec("tabChequeo");
spec.setContent(R.id.tabChequeo);
spec.setIndicator("Chequeo");
tabs.addTab(spec);
spec = tabs.newTabSpec("tabServicios");
spec.setContent(R.id.tabServicios);
spec.setIndicator("Servicios consumidos");
tabs.addTab(spec);
spec = tabs.newTabSpec("tabObservaciones");
spec.setContent(R.id.tabObservaciones);
spec.setIndicator("Observaciones");
tabs.addTab(spec);
tabs.setCurrentTab(0);
}
public void listarChequeoEncuesta(){
try{
oDB = new DBProvider(this);
Intent intent = getIntent();
int idBien = intent.getIntExtra("id_bien", 0);
int idEncuestaPreentrega = intent.getIntExtra("id_encuestapreentrega", 0);
String[][] arrayChequeoEncuesta = oDB.traerEncuestaPostventa(idBien,
idEncuestaPreentrega);
if(!(arrayChequeoEncuesta == null)){
for(int i=0; i<arrayChequeoEncuesta.length; i++){
int idEncuestaPostventa = Integer.parseInt(arrayChequeoEncuesta[i][0]);
int idEncuestaDetalle = Integer.parseInt(arrayChequeoEncuesta[i][1]);
String item = arrayChequeoEncuesta[i][2];
Boolean recepcion = (Integer.parseInt(arrayChequeoEncuesta[i][3]) != 0);
String observacion =arrayChequeoEncuesta[i][4];
listaChequeoEncuesta.add(new EncuestaPostventa(idEncuestaPostventa,
idEncuestaDetalle,
item,
recepcion,
observacion));
}
}
adapter = new EncuestaPostventaAdapter(this, listaChequeoEncuesta);
lvChequeoEncuesta = (ListView) findViewById(R.id.lvChequeoEncuesta);
lvChequeoEncuesta.setAdapter(adapter);
}catch(Exception e){
Toast.makeText(this, "Error (listarChequeoEncuesta): " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public void listarConsumoBien(){
try{
oDB = new DBProvider(this);
Intent intent = getIntent();
int argIdBien = intent.getIntExtra("id_bien", 0);
int argIdEmpsa = intent.getIntExtra("id_empsa", 0);
String[][] arrayConsumoBien = oDB.traerConsumoBien(argIdBien,
argIdEmpsa);
if(!(arrayConsumoBien == null)){
for(int i=0; i<arrayConsumoBien.length; i++){
int idConsumoBien = Integer.parseInt(arrayConsumoBien[i][0]);
int idBien = Integer.parseInt(arrayConsumoBien[i][1]);
int idDominio = Integer.parseInt(arrayConsumoBien[i][2]);
String nombre = arrayConsumoBien[i][3];
String unidad = arrayConsumoBien[i][4];
int cantidad = Integer.parseInt(arrayConsumoBien[i][5]);
Boolean estado = (Integer.parseInt(arrayConsumoBien[i][6]) != 0);
listaConsumoBien.add(new ConsumoBien(idConsumoBien,
idBien,
idDominio,
nombre,
unidad,
cantidad,
estado));
}
}
adapterConsumoBien = new ConsumoBienAdapter(this, listaConsumoBien);
lvConsumoBien = (ListView) findViewById(R.id.lvConsumoBien);
lvConsumoBien.setAdapter(adapterConsumoBien);
}catch(Exception e){
Toast.makeText(this, "Error (listarConsumoBien): " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
}
public void onNothingSelected(AdapterView<?> parent)
{
}
}
And its layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:parentActivityName="net.gestionwireless.officemovil.inmobiliario.PostventaPreentregaActivity">
<TabHost android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvLabelProyecto"
android:text="#string/proyecto"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvProyecto"
android:text=""
android:layout_toRightOf="#id/tvLabelProyecto" />
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvLabelRut"
android:layout_below="#id/tvLabelProyecto"
android:text="#string/rut"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvRut"
android:text=""
android:layout_toRightOf="#id/tvLabelRut"
android:layout_below="#id/tvProyecto" />
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvLabelCliente"
android:layout_marginLeft="50dp"
android:layout_below="#id/tvLabelProyecto"
android:layout_toRightOf="#id/tvRut"
android:text="#string/cliente" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvCliente"
android:text=""
android:layout_toRightOf="#id/tvLabelCliente"
android:layout_below="#id/tvProyecto" />
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvLabelDireccion"
android:layout_below="#id/tvCliente"
android:text="#string/direccion"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/texto_L"
android:id="#+id/tvDireccion"
android:text=""
android:layout_toRightOf="#id/tvLabelDireccion"
android:layout_below="#id/tvCliente" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/tvDireccion">
<TabWidget android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/tabs" />
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/tabcontent">
<LinearLayout
android:id="#+id/tabChequeo"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp">
<TextView
android:text="#string/titulo_grilla_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".33"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
<TextView
android:text="#string/titulo_grilla_recepcion"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
<TextView
android:text="#string/titulo_grilla_observacion"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".57"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
</LinearLayout>
<ListView
android:id="#+id/lvChequeoEncuesta"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
</ListView>
</LinearLayout>
<LinearLayout
android:id="#+id/tabServicios"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp">
<TextView
android:text="#string/titulo_grilla_servicio"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".4"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
<TextView
android:text="#string/titulo_grilla_recepcion"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
<TextView
android:text="#string/titulo_grilla_consumo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".3"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
<TextView
android:text="#string/titulo_grilla_unidad"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".2"
android:gravity="center"
android:textSize="#dimen/titulo_grilla"
android:textStyle="bold" />
</LinearLayout>
<ListView
android:id="#+id/lvConsumoBien"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
</ListView>
</LinearLayout>
<LinearLayout android:id="#+id/tabObservaciones"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/etObservaciones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/hint_observaciones" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</RelativeLayout>
</TabHost>
</LinearLayout>
The class for each item:
package net.gestionwireless.officemovil.inmobiliario;
public class EncuestaPostventa {
private int idEncuestaPostventa;
private int idEncuestaDetalle;
private String item;
private Boolean recepcion;
private String observacion;
public EncuestaPostventa(int idEncuestaPostventa,
int idEncuestaDetalle,
String item,
Boolean recepcion,
String observacion) {
this.idEncuestaPostventa = idEncuestaPostventa;
this.idEncuestaDetalle = idEncuestaDetalle;
this.item = item;
this.recepcion = recepcion;
this.observacion = observacion;
}
public int traerIdEncuestaPostventa() {
return idEncuestaPostventa;
}
public void asignarIdEncuestaPostventa(int idEncuestaPostventa) {
this.idEncuestaPostventa = idEncuestaPostventa;
}
public int traerIdEncuestaDetalle() {
return idEncuestaDetalle;
}
public void asignarIdEncuestaDetalle(int idEncuestaDetalle) {
this.idEncuestaDetalle = idEncuestaDetalle;
}
public String traerItem() {
return item;
}
public void asignarItem(String item) {
this.item = item;
}
public Boolean traerRecepcion() {
return recepcion;
}
public void asignarRecepcion(Boolean recepcion) {
this.recepcion = recepcion;
}
public String traerObservacion() {
return observacion;
}
public void asignarObservacion(String observacion) {
this.observacion = observacion;
}
}
package net.gestionwireless.officemovil.inmobiliario;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
The adapter:
public class EncuestaPostventaAdapter extends ArrayAdapter<EncuestaPostventa> {
private Context context;
private ArrayList<EncuestaPostventa> datos;
public EncuestaPostventaAdapter(Context context, ArrayList<EncuestaPostventa> datos) {
super(context, R.layout.encuestapostventa_item, datos);
this.context = context;
this.datos = datos;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View item = LayoutInflater.from(context).inflate(
R.layout.encuestapostventa_item, null);
TextView tvItem = (TextView) item.findViewById(R.id.tvItem);
tvItem.setText(datos.get(position).traerItem());
CheckBox chkRecepcion = (CheckBox) item.findViewById(R.id.chkRecepcion);
chkRecepcion.setChecked(datos.get(position).traerRecepcion());
EditText editObservacion = (EditText) item.findViewById(R.id.editObservacion);
editObservacion.setText(datos.get(position).traerObservacion());
return item;
}
}
And the layout for each item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="horizontal">
<TextView
android:id="#+id/tvItem"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".33"
android:textSize="#dimen/texto_L" />
<CheckBox
android:id="#+id/chkRecepcion"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".1"/>
<EditText
android:id="#+id/editObservacion"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".57"
android:textSize="#dimen/texto_L"
android:inputType="textCapSentences" />
</LinearLayout>
If you put a log statement in your ArrayAdapter.getView(), you'll realize what's going on in two seconds.
As the list is scrolled, a list item that you edited is scrolled out of view. When the item is scrolled back into view, the view is recreated and getView() is called. Since your adapter doesn't have a representation of the changes that were made previously, getView() recreates the view with the original unedited data.
If that's happening to you on focus lost, that must mean that the focus-lost event is triggering a view update on the list item. I've never done editing in a list item, so I'm not familiar with that behavior.
You need to put event listeners on your EditText and CheckBox that store their edited state somewhere. Then your adapter needs to use that edit state when creating the list items.
You might have to write a more complex adapter that extends BaseAdapter directly. The adapter is the Model for your list View, and there's no state in a ListView except for your adapter. In the case of ListView, the view can update any part of its list at any time, so the adapter has to have the current model data for the ListView at all times.

Categories

Resources