Summing EditText values in an Android TextWatcher - java

Image
I have a RecyclerView in which fields are created dynamically. To save the stored data, I used TextWatcher. But I do not know how I sum up the values that are in EditText -Cost and display the value in the TextView at the bottom of the screen
public class ItemsAdapter extends
ListAdapter<Item,ItemsAdapter.ViewHolder> {
private List<Item> mItems=new ArrayList<>();
public static final DiffUtil.ItemCallback<Item>DIFF_CALLBACK=
new DiffUtil.ItemCallback<Item>() {
#Override
public boolean areItemsTheSame( Item oldItem, Item newItem) {
return oldItem.getId()==newItem.getId();
}
#Override
public boolean areContentsTheSame(Item oldItem, Item newItem) {
return(oldItem.getName()==newItem.getName()&&oldItem.getCost()==newItem.getCost());
}
};
public ItemsAdapter(){super(DIFF_CALLBACK);}
public void addMorreItems(List<Item> newItems){
int insertionPosition=mItems.size();
mItems.addAll(newItems);
notifyItemRangeInserted(insertionPosition,newItems.size());
submitList(mItems);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
Context context=parent.getContext();
LayoutInflater inflater=LayoutInflater.from(context);
View itemView=inflater.inflate(R.layout.custom_edittext_layout,parent,false);
ViewHolder viewHolder=new ViewHolder(itemView);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder,int position){
viewHolder.editTextName.setText(mItems.get(position).getName());
viewHolder.editTextCost3.setText(mItems.get(position).getCost());
Item item=getItem(position);
EditText editText=viewHolder.editTextName;
editText.setText(item.getName());
EditText editText1=viewHolder.editTextCost3;
editText1.setText(item.getCost());
}
public class ViewHolder extends RecyclerView.ViewHolder {
public EditText editTextName;
public EditText editTextCost3;
public TextView txtTipAmount3;
public Button buttonDelete;
public Button buttonOK;
public ViewHolder(View itemView){
super(itemView);
editTextCost3=(EditText)itemView.findViewById(R.id.ediCost3);
editTextName=(EditText)itemView.findViewById(R.id.editTextEnterYourName);
txtTipAmount3=(TextView)itemView.findViewById(R.id.txtTipAmount3);
buttonDelete=(Button)itemView.findViewById(R.id.buttonDelete);
buttonOK=(Button)itemView.findViewById(R.id.buttonOk);
buttonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position=getAdapterPosition();
try {
mItems.remove(position);
notifyItemRemoved(position);
}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}
}
});
editTextName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mItems.get(getAdapterPosition()).setmName(editTextName.getText().toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
editTextCost3.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mItems.get(getAdapterPosition()).setmCost(editTextCost3.getText().toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
} }

Add callback for the Activity/Fragment that holds TextView for sum cost:
interface OnCostChangeListener {
void onChange(List<Item> list);
}
Implement it:
class MyActivity extends AppCompatActivity implements OnCostChangeListener {
//...
#Override
public void onChange(List<Item> list) {
int sum = 0;
for (Item it : list) {
sum += it.getCost();
}
((TextView) findViewById(R.id.totalCost)).setText(String.valueOf(sum));
}
//...
}
Subscribe the adapter:
private OnCostChangeListener mListener;
public ItemsAdapter(OnCostChangeListener listener){
super(DIFF_CALLBACK);
this.mListener = listener;
}
and use the listener in TextWatcher:
editTextCost3.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mItems.get(getAdapterPosition()).setmCost(editTextCost3.getText().toString());
if (mListener != null) {
mListener.onChange(mItems);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
UPD. It's supposed cost is stored in Item as number (integer, in the sample), not string

Related

Android Studio - How to get data from an EditText in a RecyclerView and put them into an ArrayList in the main activity?

So I have a RecyclerView consisting of EditTexts that uses an ArrayList as its data set, when the EditTexts are edited I want that ArrayList to be updated as well and I want to be able to use it in the Main Activity currently I've tried implementing a TextChangedListener however I have no clue how to get the data and transfer it to my list. Here's the code:
Main Activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
public ArrayList playerList;
private Button runItButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerList = new ArrayList();
for(int i = 0; i < 4; i++){
playerList.add("Player " + (i + 1));
}
runItButton = findViewById(R.id.buttonStartGame);
runItButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, DrinktasksActivity.class);
intent.putExtra("playerList", playerList);
startActivity(intent);
}
});
recyclerView = findViewById(R.id.recyclyerViewNames);
MyAdapter myAdapter = new MyAdapter(this, playerList);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public void addPlayers(View view){
playerList.add("Player " + (playerList.size() + 1));
recyclerView.getAdapter().notifyDataSetChanged();
}
}
The adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
Context context;
ArrayList playerList;
public MyAdapter(Context ct, List players){
context = ct;
playerList = (ArrayList) players;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.enter_name, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
String current = playerList.get(position).toString();
holder.editText.setHint(current);
holder.editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// The code I assume should go here but I don't know how to implement
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public int getItemCount() {
return playerList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
EditText editText;
public ViewHolder(#NonNull View itemView) {
super(itemView);
editText = itemView.findViewById(R.id.editname);
}
}
}
All you have to do is to implement a custom callback to your activity with the index in which the edittext is edited and what is the new text.
Create a callback interface inside adapter
public interface TextChangeCallback {
void textChangedAt(int position, String text);
}
Pass the inteface implementation to Adapter via constructor
public MyAdapter(Context ct, List players,TextChangeCallback callback){
context = ct;
playerList = (ArrayList) players;
this.callback = callback;
}
Trigger callback to activity whenever you edit the text using TextWatcher
holder.editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.equals("")){
return;
}
data.set(position, String.valueOf(s));
callback.textChangedAt(position, String.valueOf(s));
}
#Override
public void afterTextChanged(Editable s) {
}
});
Add this interface implementation to your adapter
MyAdapter myAdapter = new MyAdapter(this, playerList, new MyAdapter.TextChangeCallback() {
#Override
public void textChangedAt(int position, String text) {
playerList.set(position, text);
Log.d("UPDATED LIST : ", String.valueOf(data));
}
});
recyclerView.setAdapter(myAdapter);
This will now update the ArrayList in adapter and activity as you edit the edittext from recyclerview.
You can find the complete implementation from this link

Check if edit text is empty [duplicate]

This question already has answers here:
How do I check if my EditText fields are empty? [closed]
(30 answers)
Closed 2 years ago.
I have tried other questions and answer but have not found a solution.
I am creating a social app that let's people search for others. When I click the search bar I want and type in a letter, for e.g. B, I see the list of users with the name B as expected. But when I removed the B and the search bar is empty, the list of users still shows up.
When nothing is in the search bar, I want the list of users to disappear. This is how I create the edit text in my activity_search:
<EditText
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:hint="Search Username Here"
android:textSize="22dp"
android:id="#+id/input"
android:inputType="text"
android:layout_gravity="center"
android:background="#drawable/round_edit_text" />
This is where I set that edit text in the java activity:
input = findViewById(R.id.input);
And this is the whole java file:
EditText input;
RecyclerView FindFriendsRecyclerList;
DatabaseReference mRef;
Query query;
Context mContext;
TextWatcher textWacher;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
input = findViewById(R.id.input);
input.addTextChangedListener(textWacher);
TextWatcher textWacher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String strText = s.toString();
if (strText .length() == 0) {
// removeList();
FindFriendsRecyclerList.setVisibility(View.INVISIBLE);
Toast.makeText(mContext, "Remove list", Toast.LENGTH_SHORT).show();
} else {
// showList();
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
FindFriendsRecyclerList = (RecyclerView) findViewById(R.id.recycler);
FindFriendsRecyclerList.setLayoutManager(new LinearLayoutManager(this));
findViewById(R.id.search).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mRef = FirebaseDatabase.getInstance().getReference().child("Users");
query = mRef.orderByChild("fullname").orderByChild("username").startAt(input.getText().toString()).endAt(input.getText().toString()+"\uf8ff");
setdata();
}
});
checkIfEmpty();
if (input.getText().toString().length() == 0) {
FindFriendsRecyclerList.setVisibility(View.INVISIBLE);
}
}
private void setdata() {
FirebaseRecyclerOptions<User> options =
new FirebaseRecyclerOptions.Builder<User>()
.setQuery(query, User.class)
.build();
FirebaseRecyclerAdapter<User, FindFriendsViewHolder> adapter =
new FirebaseRecyclerAdapter<User, FindFriendsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull FindFriendsViewHolder holder, final int position, #NonNull User model) {
holder.userName.setText(model.getUsername());
holder.userFullName.setText(model.getFullname());
Picasso.get().load(model.getImageurl()).placeholder(R.drawable.profile_pic).into(holder.profileImage);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//String visit_user_id = getRef(position).getKey();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.search_users, new ProfileFragment()).commit();
}
});
}
#NonNull
#Override
public FindFriendsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.user_item, viewGroup, false);
FindFriendsViewHolder viewHolder = new FindFriendsViewHolder(view);
return viewHolder;
}
};
FindFriendsRecyclerList.setAdapter(adapter);
adapter.startListening();
}
public static class FindFriendsViewHolder extends RecyclerView.ViewHolder {
public TextView userName, userFullName;
public CircleImageView profileImage;
public FindFriendsViewHolder(#NonNull View itemView) {
super(itemView);
userName = itemView.findViewById(R.id.username);
userFullName = itemView.findViewById(R.id.fullname);
profileImage = itemView.findViewById(R.id.image_profile);
}
}
public void checkIfEmpty() {
TextWatcher textWacher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String strText = s.toString();
if (strText.length() == 0) {
FindFriendsRecyclerList.setVisibility(View.INVISIBLE);
} else {
// showList();
}
}
#Override
public void afterTextChanged(Editable s) {
FindFriendsRecyclerList.setVisibility(View.INVISIBLE);
}
};
}
As you can see above I have tried the following two ways to check if it's empty:
if (input.getText().toString().length() == 0) {
FindFriendsRecyclerList.setVisibility(View.INVISIBLE);
}
public void checkIfEmpty(View v){
if(input.getText().toString().equals("")) {
input.setVisibility(View.INVISIBLE);
}
}
You only call checkIfEmpty on method onCreate if you want yo check on every change if an EditText is empty you need to add to your "input" EditText an onDataChangeListener and check on every mover if is empty.
use TextWatcher for get text state in EditText.
for example,
public class MainActivity extends AppCompatActivity {
private EditText input;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
input = (EditText) findViewById(R.id.input);
input.addTextChangedListener(textWacher);
}
TextWatcher textWacher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String strText = s.toString();
if (strText .length() == 0) {
// removeList();
Toast.makeText(MainActivity.this, "remove", Toast.LENGTH_SHORT).show();
} else {
// showList();
Toast.makeText(MainActivity.this, "show", Toast.LENGTH_SHORT).show();
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
}

Android RecyclerView With EditText Shuffling Problem

I Am Trying to Implement RecyclerView With EditText. First I Am Fetching Members List From Database And then for each member I want to get value from user input(EditText).
But when I submit data, values for the members are getting shuffled.
I Am Using TextWatcher Class, When Text Get changed it adds value in the model class.
Values are getting shuffled when I scroll the RecyclerView.
I tried all the solutions on the stack overflow but none of it worked
following is my code:
For Fetching the data:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
ProgressBar progressBar;
LinearLayoutManager manager;
String URL = "members_fetch.php?club_id=98";
List<MemberListDetails> memberListDetailsList = new ArrayList<>();
private LinearLayoutManager layoutManager;
MemberListDetails memberListDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progress);
Button button = findViewById(R.id.button);
recyclerView = findViewById(R.id.my_recycler_view);
manager = new LinearLayoutManager(this);
initRecyclerView();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String z = ((Adapter) recyclerView.getAdapter()).getValue().toString();
Log.wtf("aaa", z);
}
});
getMembersDetails();
}
private void initRecyclerView() {
layoutManager = new LinearLayoutManager(this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
}
private void getMembersDetails() {
final ProgressDialog pd = new ProgressDialog(this);
pd.setMessage("Loading Members Details");
pd.show();
pd.setCancelable(false);
pd.setCanceledOnTouchOutside(false);
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.dismiss();
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
Log.d("ssdf", "fsdf" + response);
JSONObject o = jsonArray.getJSONObject(i);
memberListDetails = new MemberListDetails();
memberListDetails.setStatus(o.getString("status"));
memberListDetails.setMembership_id(o.getString("membership_id"));
memberListDetails.setFirst_name(o.getString("first_name"));
memberListDetails.setMiddle_name(o.getString("middle_name"));
memberListDetails.setLast_name(o.getString("last_name"));
memberListDetails.setClub_post(o.getString("club_post"));
memberListDetails.setDistrict_post(o.getString("district_post"));
memberListDetails.setGender(o.getString("gender"));
memberListDetails.setPost_name(o.getString("post_name"));
memberListDetailsList.add(memberListDetails);
Log.d("hhhhh", "xxxx" + memberListDetailsList);
}
recyclerView.setAdapter(new Adapter(memberListDetailsList, MainActivity.this));
} catch (Exception e) {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("errorMsg", "dddd" + error.getMessage());
pd.dismiss();
}
});
queue.add(stringRequest);
}
}
For Adapter Class :
public class Adapter extends RecyclerView.Adapter<Adapter.VHolder> {
private List<MemberListDetails> data;
Context context;
EditText text;
Integer pos;
public Adapter(List<MemberListDetails> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public Adapter.VHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item, viewGroup, false);
return new VHolder(view);
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public List<MemberListDetails> getItems() {
return data;
}
#Override
public void onBindViewHolder(#NonNull Adapter.VHolder vHolder, int i) {
vHolder.setIsRecyclable(false);
vHolder.textView.setText(data.get(i).getFirst_name());
text = vHolder.editText;
pos = i;
text.setText(data.get(i).getValue());
text.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// text.setError(null);
data.get(pos).setValue(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// text.setError(null);
data.get(pos).setValue(s.toString());
}
});
}
public class VHolder extends RecyclerView.ViewHolder {
TextView textView;
EditText editText;
public VHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv_textView);
editText = itemView.findViewById(R.id.editText2);
}
}
String getValue() {
StringBuffer x = new StringBuffer();
for (MemberListDetails a : data) {
x.append(a.getValue()+",");
}
return x.substring(0,x.length()-1);
}
}
I think you need to remove global edit text and position. Also, add text watcher in holder class. Please check below code. it may help you.
public class Adapter extends RecyclerView.Adapter<Adapter.VHolder> {
private List<MemberListDetails> data;
Context context;
public Adapter(List<MemberListDetails> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public Adapter.VHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item, viewGroup, false);
return new VHolder(view);
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public List<MemberListDetails> getItems() {
return data;
}
#Override
public void onBindViewHolder(#NonNull Adapter.VHolder vHolder, int i) {
vHolder.setIsRecyclable(false);
vHolder.textView.setText(data.get(i).getFirst_name());
vHolder.editText.removeTextChangedListener(vHolder.textWatcher);
vHolder.editText.setText(data.get(i).getValue());
vHolder.editText.addTextChangedListener(vHolder.textWatcher);
}
public class VHolder extends RecyclerView.ViewHolder {
TextView textView;
EditText editText;
TextWatcher textWatcher;
public VHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv_textView);
editText = itemView.findViewById(R.id.editText2);
textWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// text.setError(null);
data.get(getAdapterPosition()).setValue(s.toString());
}
};
}
}
String getValue() {
StringBuffer x = new StringBuffer();
for (MemberListDetails a : data) {
x.append(a.getValue()+",");
}
return x.substring(0,x.length()-1);
}
Here is the solution. It may contain some error because I am not able to compile if due unavailable of resources like xml file and Model class But it definitely works for you. Because I have implemented the same in my project and working fine
public class Adapter extends RecyclerView.Adapter<Adapter.VHolder> {
private List<MemberListDetails> data;
Context context;
Integer pos;
public Adapter(List<MemberListDetails> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public Adapter.VHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item, viewGroup, false);
return new VHolder(view);
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public List<String> getItems() {
return data;
}
#Override
public void onBindViewHolder(#NonNull Adapter.VHolder vHolder, int i) {
vHolder.setIsRecyclable(false);
vHolder.textView.setText(data.get(i).getFirst_name());
pos = i;
vHolder.myCustomEditTextListener.updatePosition(vHolder.getAdapterPosition());
vHolder.editText.setText(data.get(vHolder.getAdapterPosition()));
}
public class VHolder extends RecyclerView.ViewHolder {
TextView textView;
EditText editText;
public MyCustomEditTextListener myCustomEditTextListener;
public VHolder(View itemView, MyCustomEditTextListener myCustomEditTextListener) {
super(itemView);
textView = itemView.findViewById(R.id.tv_textView);
editText = itemView.findViewById(R.id.editText2);
this.editText.addTextChangedListener(myCustomEditTextListener);
}
}
String getValue() {
StringBuffer x = new StringBuffer();
for (MemberListDetails a : data) {
x.append(a.getValue() + ",");
}
return x.substring(0, x.length() - 1);
}
private class MyCustomEditTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// no op
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
data.set(position, charSequence.toString());
}
#Override
public void afterTextChanged(Editable editable) {
// no op
}
}
}

How to fix 'java.lang.ClassCastException: Activity must implement fragment's callbacks'

I am a beginner who am writing a code that consists of two activities. Both have their own Fragments. On the first activity (in its fragment), the user input some fields. The result will be displayed on the second activity (in its list fragment).
I have tried to get state manually using bundle. And now, I am using callback to do that. However, I got an error message java.lang.ClassCastException: Activity must implement fragment's callbacks.
The first activity is:
public class AssetRegistrationInfoPage extends Page {
public static final String ASSET_TYPE_NAME_KEY = "assetTypeName";
public static final String ASSET_ID_DATA_KEY = "assetID";
public static final String PROJECT_CODE_DATA_KEY = "projectCode";
public static final String REMARK_DATA_KEY = "remark";
public AssetRegistrationInfoPage(ModelCallbacks callbacks, String title) {
super(callbacks, title);
}
#Override
public Fragment createFragment() {
return AssetRegistrationInfoFragment.create(getKey());
}
#Override
public void getReviewItems(ArrayList<ReviewItem> dest) {
dest.add(new ReviewItem("Nama Asset", mData.getString(ASSET_TYPE_NAME_KEY), getKey(), 0, null));
dest.add(new ReviewItem("Kode Asset", mData. getString(ASSET_ID_DATA_KEY), getKey(), 0, null));
dest.add(new ReviewItem("Kode Project", mData.getString(PROJECT_CODE_DATA_KEY), getKey(),0,null));
dest.add(new ReviewItem("Kondisi Asset", mData.getString(REMARK_DATA_KEY), getKey(), 0, null));
}
#Override
public boolean isCompleted() {
return (!TextUtils.isEmpty(mData.getString(ASSET_TYPE_NAME_KEY)) &&
!TextUtils.isEmpty(mData.getString(ASSET_ID_DATA_KEY)) &&
!TextUtils.isEmpty(mData.getString(PROJECT_CODE_DATA_KEY)) &&
!TextUtils.isEmpty(mData.getString(REMARK_DATA_KEY)));
}
}
The first fragment:
public class AssetRegistrationInfoFragment extends Fragment {
private static final String ARG_KEY = "key";
private PageFragmentCallbacks mCallbacks;
private String mKey;
private AssetRegistrationInfoPage mPage;
private TextView mAssetID;
private AutoCompleteTextView mAssetTypeName, mProjectCode;
private TextView mRemark;
private Button mTakePicture;
static final int REQUEST_PICTURE_CAPTURE = 1;
private String pictureFilePath;
Bitmap bitmap;
ImageView mImgView;
ArrayList<String> projectCodes = new ArrayList<String>();
ArrayList<String> assetTypeNames = new ArrayList<String>();
public static AssetRegistrationInfoFragment create(String key) {
Bundle args = new Bundle();
args.putString(ARG_KEY, key);
AssetRegistrationInfoFragment fragment = new AssetRegistrationInfoFragment();
fragment.setArguments(args);
return fragment;
}
public AssetRegistrationInfoFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mKey = args.getString(ARG_KEY);
mPage = (AssetRegistrationInfoPage) mCallbacks.onGetPage(mKey);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
boolean cancel = false;
mAssetTypeName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1,
int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
mPage.getData().putString(AssetRegistrationInfoPage.ASSET_TYPE_NAME_KEY,
(editable != null) ? editable.toString() : null);
mPage.notifyDataChanged();
}
});
mAssetID.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1,
int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
mPage.getData().putString(AssetRegistrationInfoPage.ASSET_ID_DATA_KEY,
(editable != null) ? editable.toString() : null);
mPage.notifyDataChanged();
}
});
mProjectCode.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1,
int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
mPage.getData().putString(AssetRegistrationInfoPage.PROJECT_CODE_DATA_KEY,
(editable != null) ? editable.toString() : null);
mPage.notifyDataChanged();
}
});
mRemark.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1,
int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
mPage.getData().putString(AssetRegistrationInfoPage.REMARK_DATA_KEY,
(editable != null) ? editable.toString() : null);
mPage.notifyDataChanged();
}
});
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_page_asset_registration_info, container, false);
((TextView) view.findViewById(android.R.id.title)).setText(mPage.getTitle());
getAssetType();
mAssetTypeName = ((AutoCompleteTextView) view.findViewById(R.id.assetTypeName));
mAssetTypeName.setText(mPage.getData().getString(AssetRegistrationInfoPage.ASSET_TYPE_NAME_KEY));
ArrayAdapter<String> assetTypeNameAdapter = new ArrayAdapter<String>
(getActivity(), android.R.layout.simple_dropdown_item_1line, assetTypeNames);
mAssetTypeName.setAdapter(assetTypeNameAdapter);
mAssetID = ((TextView) view.findViewById(R.id.assetID));
mAssetID.setText(mPage.getData().getString(AssetRegistrationInfoPage.ASSET_ID_DATA_KEY));
getProjects();
mProjectCode = ((AutoCompleteTextView) view.findViewById(R.id.projectCode));
mProjectCode.setText(mPage.getData().getString(AssetRegistrationInfoPage.PROJECT_CODE_DATA_KEY));
mProjectCode.setThreshold(1);
ArrayAdapter<String> projectCodeAdapter = new ArrayAdapter<String>
(getActivity(), android.R.layout.simple_dropdown_item_1line, projectCodes);
mProjectCode.setAdapter(projectCodeAdapter);
mRemark = ((TextView) view.findViewById(R.id.remark));
mRemark.setText(mPage.getData().getString(AssetRegistrationInfoPage.REMARK_DATA_KEY));
return view;
}
private void getProjects() {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<List<Project>> call = apiService.getProjects("");
call.enqueue(new Callback<List<Project>>() {
#Override
public void onResponse(Call<List<Project>> call, Response<List<Project>> response) {
for (Project project : response.body()) {
projectCodes.add(project.getProjectCode());
}
}
#Override
public void onFailure(Call<List<Project>> call, Throwable t) {
Toast.makeText(getActivity(), "Unable to fetch Data " , Toast.LENGTH_LONG).show();
}
});
}
private void getAssetType() {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<List<AssetType>> call = apiService.getAssetTypes("");
call.enqueue(new Callback<List<AssetType>>() {
#Override
public void onResponse(Call<List<AssetType>> call, Response<List<AssetType>> response) {
for (AssetType assetType : response.body()) {
assetTypeNames.add(assetType.getName());
}
}
#Override
public void onFailure(Call<List<AssetType>> call, Throwable t) {
Toast.makeText(getActivity(), "Unable to fetch Data ", Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof PageFragmentCallbacks)) {
throw new ClassCastException("Activity must implement PageFragmentCallbacks");
}
mCallbacks = (PageFragmentCallbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
// In a future update to the support library, this should override setUserVisibleHint
// instead of setMenuVisibility.
if ( mAssetTypeName != null && mAssetID != null && mProjectCode != null && mRemark != null){
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
if (!menuVisible) {
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
}
}
}
The second page
public class AssetRegConfirmationPage extends Page {
public static final String ASSET_TYPE_NAME_KEY = "assetTypeName";
public AssetRegConfirmationPage(ModelCallbacks callbacks, String title) {
super(callbacks, title);
}
#Override
public Fragment createFragment() {
return AssetRegConfirmationFragment.create(getKey());
}
#Override
public void getReviewItems(ArrayList<ReviewItem> dest) {
dest.add(new ReviewItem("Nama Asset", mData.getString(ASSET_TYPE_NAME_KEY), getKey(), 0, null));
}
}
The second fragment
public class AssetRegConfirmationFragment extends ListFragment implements ModelCallbacks {
private static final String ARG_KEY = "key";
private Callbacks mCallbacks;
private AbstractWizardModel mWizardModel;
private List<ReviewItem> mCurrentReviewItems;
private ReviewAdapter mReviewAdapter;
public AssetRegConfirmationFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReviewAdapter = new ReviewAdapter();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_page, container, false);
TextView titleView = (TextView) rootView.findViewById(android.R.id.title);
titleView.setText(R.string.review);
titleView.setTextColor(getResources().getColor(R.color.colorPrimaryOld));
ListView listView = (ListView) rootView.findViewById(android.R.id.list);
setListAdapter(mReviewAdapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new ClassCastException("Activity must implement fragment's callbacks");
}
mCallbacks = (Callbacks) activity;
mWizardModel = mCallbacks.onGetModel();
mWizardModel.registerListener(this);
onPageTreeChanged();
}
#Override
public void onPageTreeChanged() {
onPageDataChanged(null);
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
mWizardModel.unregisterListener(this);
}
#Override
public void onPageDataChanged(Page changedPage) {
ArrayList<ReviewItem> reviewItems = new ArrayList<ReviewItem>();
for (Page page : mWizardModel.getCurrentPageSequence()) {
page.getReviewItems(reviewItems);
}
Collections.sort(reviewItems, new Comparator<ReviewItem>() {
#Override
public int compare(ReviewItem a, ReviewItem b) {
return a.getWeight() > b.getWeight() ? +1 : a.getWeight() < b.getWeight() ? -1 : 0;
}
});
mCurrentReviewItems = reviewItems;
if (mReviewAdapter != null) {
mReviewAdapter.notifyDataSetInvalidated();
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
mCallbacks.onEditScreenAfterReview(mCurrentReviewItems.get(position).getPageKey());
}
public interface Callbacks {
AbstractWizardModel onGetModel();
void onEditScreenAfterReview(String pageKey);
}
private class ReviewAdapter extends BaseAdapter {
#Override
public boolean hasStableIds() {
return true;
}
#Override
public int getItemViewType(int position) {
return 0;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public boolean areAllItemsEnabled() {
return true;
}
#Override
public Object getItem(int position) {
return mCurrentReviewItems.get(position);
}
#Override
public long getItemId(int position) {
return mCurrentReviewItems.get(position).hashCode();
}
#Override
public View getView(int position, View view, ViewGroup container) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
View rootView = inflater.inflate(R.layout.list_item_review, container, false);
ReviewItem reviewItem = mCurrentReviewItems.get(position);
String value = reviewItem.getDisplayValue();
if (TextUtils.isEmpty(value)) {
value = "(None)";
}
((TextView) rootView.findViewById(android.R.id.text1)).setText(reviewItem.getTitle());
((TextView) rootView.findViewById(android.R.id.text2)).setText(value);
return rootView;
}
#Override
public int getCount() {
return mCurrentReviewItems.size();
}
}
public static AssetRegConfirmationFragment create(String key) {
Bundle args = new Bundle();
args.putString(ARG_KEY, key);
AssetRegConfirmationFragment fragment = new AssetRegConfirmationFragment();
fragment.setArguments(args);
return fragment;
}
}
I have no idea of what should I do to make this work.
Here is the Page source code:
public abstract class Page implements PageTreeNode {
/**
* The key into {#link #getData()} used for wizards with simple (single) values.
*/
public static final String SIMPLE_DATA_KEY = "_";
protected ModelCallbacks mCallbacks;
/**
* Current wizard values/selections.
*/
protected Bundle mData = new Bundle();
protected String mTitle;
protected boolean mRequired = false;
protected String mParentKey;
protected Page(ModelCallbacks callbacks, String title) {
mCallbacks = callbacks;
mTitle = title;
}
public Bundle getData() {
return mData;
}
public String getTitle() {
return mTitle;
}
public boolean isRequired() {
return mRequired;
}
void setParentKey(String parentKey) {
mParentKey = parentKey;
}
#Override
public Page findByKey(String key) {
return getKey().equals(key) ? this : null;
}
#Override
public void flattenCurrentPageSequence(ArrayList<Page> dest) {
dest.add(this);
}
public abstract Fragment createFragment();
public String getKey() {
return (mParentKey != null) ? mParentKey + ":" + mTitle : mTitle;
}
public abstract void getReviewItems(ArrayList<ReviewItem> dest);
public boolean isCompleted() {
return true;
}
public Bitmap getPicture() {
return mData.getParcelable(getKey() + "_" + getTitle().trim());
}
public void resetData(Bundle data) {
mData = data;
notifyDataChanged();
}
public void notifyDataChanged() {
mCallbacks.onPageDataChanged(this);
}
public Page setRequired(boolean required) {
mRequired = required;
return this;
}
}
Look at this code in second fragment:
if (!(activity instanceof Callbacks)) {
throw new ClassCastException("Activity must implement fragment's callbacks");
}
Your activity where you using second fragment should implement Callbacks interface, like:
class YourActivity implements Callbacks {
}

custom list adapter with filter doesn't work in android

hi guys i have a custom list adapter and edittext as filter, when i type anything the list disappears and nothing is being filtered
here is the filter method in the adapter class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
DataList.clear();
if (charText.length() == 0) {
DataList.addAll(arraylist);
} else {
for (Electors wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault())
.contains(charText)) {
DataList.add(wp);
}
}
}
notifyDataSetChanged();
}
and here is where i call it in the mainactivity
name.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable theWatchedText) {
String text = name.getText().toString().toLowerCase(Locale.getDefault());
Vote.this.adapter.filter(text);
}
});
any suggestion for that would be appreciated
thanks
Vote.this.adapter.getFilter().filter(s);
In onTextChanged function.
This should work for you.
you can use that in onTextChanged() method as below
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//Use this below line if you want to use it in filter method from your adapter and put the below code in that method.
//filter(editText.getText().toString());
String text = editText.getText().toString().toLowerCase();
filteredList.clear();
for (String str : arrayList){
String name = str.toLowerCase();
if(name.contains(text)) {
filteredList.add(str);
}
}
adapter.notifyDataSetChanged();
}
#Override
public void afterTextChanged(Editable s) {
}
});
whereas filtered list is your DataList.

Categories