I am making a notes app and my notes are autosaved to Firebase Database. So far a user can make their own notes but cannot edit them. I want the app to open the same note (meaning the title and desc fields will hold the data entered last time) if clicked so they can edit it but don't know how, I don't even know what to look for online as this is my first project.
New note creation & autoupdate
(One listener for title and one for body)
public class NewNoteActivity extends AppCompatActivity{
private EditText editText, etd;
private FirebaseAuth fAuth;
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference()/* THIS!*/.child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("posts").push();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_note);
editText = findViewById(R.id.etx);
etd = findViewById(R.id.etdx);
final Map<String, Object> map = new HashMap<>();
map.put("id", databaseReference.getKey());
editText.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 s) {
map.put("title", editText.getText().toString());
databaseReference.setValue(map);
}
});
etd.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 s) {
map.put("desc", etd.getText().toString());
databaseReference.setValue(map);
}
});
}
Display the notes
(and set onClick action)
adapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(options) {
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
#Override
protected void onBindViewHolder(final ViewHolder holder, final int position, final Model model) {
holder.setTxtTitle(model.getmTitle());
holder.setTxtDesc(model.getmDesc());
//holder.setmId(model.getmId());
holder.root.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Here I need to find somehow to get back to the note I clicked on
}
});
}
};
recyclerView.setAdapter(adapter);
This is how the list looks
Since I'm not able to post images yet: https://i.imgur.com/MDQ15a6.png
Each block is a note. (Ignore the B)
Related
I have recyclerView where i have added a editText. But when I type text to one edittext, text shows another edittext too. Here is the image..
Above image, I type 100 to other item, but it also shows in Settlements
Here is my adapter:
public class AdapterSectionRecycler extends SectionRecyclerViewAdapter<SectionHeader, Child, SectionViewHolder, ChildViewHolder> {
Context context;
private final OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(Child child,Boolean isChecked);
}
public AdapterSectionRecycler(Context context, List<SectionHeader> sectionItemList,OnItemClickListener listener) {
super(context, sectionItemList);
this.context = context;
this.listener = listener;
}
#Override
public SectionViewHolder onCreateSectionViewHolder(ViewGroup sectionViewGroup, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.section_item, sectionViewGroup, false);
return new SectionViewHolder(view);
}
#Override
public ChildViewHolder onCreateChildViewHolder(ViewGroup childViewGroup, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout, childViewGroup, false);
return new ChildViewHolder(view);
}
#Override
public void onBindSectionViewHolder(SectionViewHolder sectionViewHolder, int i, SectionHeader sectionHeader) {
Log.e("name section--",sectionHeader.getSectionText());
sectionViewHolder.name.setText(sectionHeader.getSectionText());
}
#Override
public void onBindChildViewHolder(ChildViewHolder childViewHolder, int i, int i1, Child child) {
childViewHolder.chk_answer.setText(child.getAnswerName());
childViewHolder.tv_surveyAnswerId.setText(String.valueOf(child.getAnswerId()));
childViewHolder.chk_answer.setChecked(false);
childViewHolder.etPercentage.setImeOptions(EditorInfo.IME_ACTION_DONE);
childViewHolder.etsl.setVisibility(View.GONE);
childViewHolder.chk_answer.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
listener.onItemClick(child,true);
}else{
listener.onItemClick(child,false);
}
}
});
childViewHolder.etPercentage.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) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
Here is my Child View holder
public class ChildViewHolder extends RecyclerView.ViewHolder {
CheckBox chk_answer;
EditText etPercentage;
EditText etsl;
TextView tv_surveyAnswerId;
public ChildViewHolder(View itemView) {
super(itemView);
chk_answer = (CheckBox) itemView.findViewById(R.id.chk_answer);
etPercentage = (EditText) itemView.findViewById(R.id.etPercentage);
etsl = (EditText) itemView.findViewById(R.id.etsl);
tv_surveyAnswerId = (TextView) itemView.findViewById(R.id.tv_surveyAnswerId);
}
}
I call from activity:
AdapterSectionRecycler adapterSectionRecycler = new AdapterSectionRecycler(this, sections, new AdapterSectionRecycler.OnItemClickListener() {
#Override
public void onItemClick(Child child, Boolean isChecked) {
}
});
recyclerView_land_conversion.setAdapter(adapterSectionRecycler);
What is the wrong with my code? Please help me..
I am trying to implement a list of edittext inside a listview. I have successfully added that by adding dynamically view inside a vertical linearlayout. Now i need to get the values from every edittext values from each main list item. Please check the image below
image file
Below is the code i am using to add dynamic edittext to the vertical linearlayout
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView != null){
return convertView;
}
convertView = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
final LinearLayout subItem = convertView.findViewById(R.id.lvSubItem);
subItem.removeAllViews();
for (final Faltu faltu : posms.get(position).getFaltus()){
View subView = LayoutInflater.from(context).inflate(R.layout.subitem,null);
final EditText subEditText = subView.findViewById(R.id.subItem);
subItem.addView(subView);
subEditText.setTag(subItem.indexOfChild(subView));
return convertView;
}
I have tried with adding textChangedListener to the editext inside the for loop and onTextChanged i haved updated my value list with the text. But unfortunately it updates all values with same value.
subEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
subEditText.requestFocus();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (s.length() > 0){
posms.get(position).getFaltus().get((Integer) subEditText.getTag()).setNumber(s.toString());
}
}
});
Any suggestion is appreciaed
Try using these lines of code
for (int i = 0; i < posms.get(position).getFaltus().size(); i++) {
final Faltu faltu = posms.get(position).getFaltus().get(i);
View subView = LayoutInflater.from(context).inflate(R.layout.subitem, null);
final EditText subEditText = subView.findViewById(R.id.subItem);
subItem.addView(subView);
subEditText.setTag(i);
subEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
subEditText.requestFocus();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (s.length() > 0){
//posms.get(position).getFaltus().get(i).setNumber(s.toString());
faltu.setNumber(s.toString());
}
}
});
}
This is from the Main Activity class. I have an arraylist of arrays and need to create a search bar for the listview.
adapter = new ArrayAdapter<String[]>(this, R.layout.list_view, android.R.id.text1, spellList)
{
public View getView(int position, View convertView, ViewGroup parent)
{
View view = super.getView(position, convertView, parent);
String[] entry = spellList.get(position);
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
TextView text2 = (TextView) view.findViewById(android.R.id.text2);
text1.setText(entry[0]);
text2.setText(entry[1]);
return view;
}
};
wizList.setAdapter(adapter);
searchText.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) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
This is the data in an Arraylist of string arrays. Prefered if searched by the spell name.
final ArrayList<String[]> spellList;
public WizardDatabase()
{
spellList = new ArrayList<>();
spellList.add(new String[] { "Resistance", "Subject gains +1 on saving throws."});
spellList.add(new String[] { "Acid Splash", "Orb deals 1d3 acid damage."});
spellList.add(new String[] { "Detech Poison", "Detects poison in one creature or small object."});
public ArrayList<String[]> getList()
{
return spellList;
}
thanks.
If it's simple String search only then use the following code
searchText.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) {
}
#Override
public void afterTextChanged(Editable s) {
if (s.length() > 3) { // it's for performance I've put 3 you can change it
adapter.getFilter().filter(s.toString());
}
}
});
ok guys
i'm developing an android app which requires lots of edittext fields(so i put them into recyclerview for better ui performance)
firstly i encountered the input values on edittext fields are not saved so scrolling caused the lose of values in edittext field
i solved the problem by adding textwatcher to edittext fields and saving input data but now im encountering another problem:
just try the following steps in proper order:
1- tap to some edittext input field(soft keyboard open ups simultaneously)
2- now scroll the recyclerview to other edittext fields (so edittext which you entering value into it, disappears from screen)
3- and try to input some words into it by keyboard
after these steps
edittext which you edited doesnt contain any value.
instead, other randomly choosen edittext gains the value which you entered
probably recyclerview's reusing mechanism is causing it, not sure
i dont want to disable scrolling when soft keyboard opened to fix this possible behaviour/issue so is there another way to solve this problem?
EDIT:
public class SampleAdapter extends RecyclerView.Adapter{
private static List<String> mEditTextValues = new ArrayList<>();
public SampleAdapter(List<String> dataSet){
mEditTextValues = dataSet;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new CustomViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.edittext,parent,false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
CustomViewHolder viewHolder = ((CustomViewHolder)holder);
viewHolder.mEditText.setTag(position);
viewHolder.mEditText.setText(mEditTextValues.get(position));
}
#Override
public int getItemCount() {
return mEditTextValues.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder{
private EditText mEditText;
public CustomViewHolder(View itemView) {
super(itemView);
mEditText = (EditText)itemView.findViewById(R.id.editText);
mEditText.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void afterTextChanged(Editable editable) {
if(mEditText.getTag()!=null){
mEditTextValues.set((int)mEditText.getTag(),editable.toString());
}
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
});
}
}
}
If you want to stop editing random place, you can hide the soft keypad when the current editing edit text starts non-focusing.
Adapter.bindView
viewHolder.mEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if (b == false) {
hideKeyboard(view.getContext(), view);
}
}
});
To hide the keypad
/**
* To hide a keypad.
*
* #param context
* #param view
*/
public static void hideKeyboard(Context context, View view) {
if ((context == null) || (view == null)) {
return;
}
InputMethodManager mgr =
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
It sounds like you need a ScrollView in your layout but there is no code posted
Try to put your TextWatcher in onBindViewHolder it will work
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
CustomViewHolder viewHolder = ((CustomViewHolder)holder);
viewHolder.mEditText.setText(mEditTextValues.get(position));
viewHolder.mEditText.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void afterTextChanged(Editable editable) {
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mEditTextValues.set(position,mEditText.getText().toString())
}
});
}
I'm new to Android development. I'm facing a dead end developing an app for a project. Please take some time and help me out.
The problem:
I am generating some EditText views nested in a LinearLayout using a for loop.
For example:
LinearLayout rootView = (LinearLayout) findViewById(R.id.rootview);
for (int i=0,j=10;i<j;i++) {
EditText et = new EditText(this);
rootView.addView(et);
et.setHint("EditText No. "+ i);
et.setId(i);
} // This code is for example purposes only.
Now, I can't seem to understand how I can set an addTextChangedListener on the EditText that is focused at a particular time and set that text on other EditTexts. Please tell me what approach should I adopt to achieve this. I tried my best to explain the problem; however, if there is still any ambiguity, feel free to comment and ask. I'm waiting for a solution to this problem.
In terms of screenshots:
What I have:
What I want:
I hope this clears things up!
**
EDIT:
Thanks to TylerSebastian for the solution. I got it to work. Here is the final code: (Inside OnCreate() method)
final LinearLayout rootView = (LinearLayout) findViewById(R.id.rootview);
for (int i=0,j=10;i<j;i++) {
final EditText et = new EditText(this);
rootView.addView(et);
et.setHint("EditText No. "+ i);
et.setId(i);
final TextWatcher textwatcher = 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) {
}
#Override
public void afterTextChanged(final Editable s) {
for (int i=0;i<10;i++){
EditText view = (EditText) findViewById(i);
if (view != et){
view.setText(s.toString());
}
}
}
};
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
et.addTextChangedListener(textwatcher);
} else {
et.removeTextChangedListener(textwatcher);
}
}
});
}
**
I don't have access to a machine with AS on it atm so no guarantee that the following is bug-free, but this should point you in the right direction:
final LinearLayout rootLayout = ...;
// within your loop
et.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(final Editable s) {
for (int i = 0; i < rootLayout.getChildCount(); i++) {
View view = rootLayout.getChildAt(i);
if (view instanceof EditText && view != et) {
((EditText) view).setText(s.toString());
}
}
}
});
edit: so the above will cause an infinite loop - see my comment below
How about:
final LinearLayout rootLayout = ...;
// again, within your loop
TextWatcher 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) {}
#Override
public void afterTextChanged(final Editable s) {
for (int i = 0; i < rootLayout.getChildCount(); i++) {
View view = rootLayout.getChildAt(i);
if (view instanceof EditText && view != et) {
((EditText) view).setText(s.toString());
}
}
}
};
et.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
((EditText) view).addTextChangedListener(textWatcher);
} else {
((EditText) view).removeTextChangedListener(textWatcher);
}
}
});
basically, only the focused element will have the textwatcher
first add a LinearLayout in your XML like that
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
then create a new class
public class EditTextCust extends RelativeLayout {
EditText status;
public EditTextCust(Context context, Model post, int inputType,TextWatcher textWatcher) {
super(context);
inflate(context, R.layout.edit_text_cust, this);
status = (EditText) findViewById(R.id.editText);
status.setInputType(inputType);
post.setData(status.getText().toString());
status.setHint(post.getHint());
status.addTextChangedListener(textWatcher);
}
public String getText() {
return status.getText().toString();
}
public EditTextCust(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextCust(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
and creat new XML file names edit_text_cust for this custom view class
<EditText
android:id="#+id/dateEditText"
android:layout_width="match_parent"
android:background="#android:color/transparent"
android:padding="#dimen/_5sdp"
android:layout_height="match_parent"
android:textSize="#dimen/_12sdp" />
and creat model class to set your data
public class Model {
String hint;
String id;
String data;
public String getHint() {
return hint;
}
public void setHint(String hint) {
this.hint = hint;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
and in your class inside the for loop but this code
Model model = new Model();
model.setHint("HINT");
model.setId("1");
editTextCust = new EditTextCust(this, editTextCustModel, InputType.TYPE_CLASS_NUMBER, 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) {
// getText from here use
s.toString();
}
#Override
public void afterTextChanged(Editable s) {
}
});
linearLayout.addView(editTextCust);
it's work with me correctly, and if you didn't understand any thing from this code just add comment and i will help you :)