Android Declaring Variables before OnCreate? - android

Is it possible to create variables before the onCreate() method in Android? I have tried doing so in the past but to no avail so I'm assuming you cant, but I just want to double check. The reason why is because I am trying to access a variable in my TextWatcher that serves as a counter, but its out of scope and asking for me to make it final, which obviously doesnt work since its serving as a counter and is needed to increment. I have attached my code below:
int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText answerText = (EditText) findViewById(R.id.answer);
final TextView text = (TextView) findViewById(R.id.wordtoanswer);
final ArrayList updatedList = helperMethod();
text.setText(updatedList.get(0).toString());
final String wordFinal = updatedList.get(0).toString();
while(true)
{
answerText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable s) {
System.out.println(counter);
String answer = s.toString();
if(answer.equals(wordFinal))
{
text.setText(updatedList.get(counter).toString());
answerText.setText("");
}
}
});
counter++;
}
}
Hopefully you guys understand why I'm trying to declare it before the onCreate(), because only then can the methods inside the TextWatcher actually access it without them being out of scope. Is there anyway I can get around this problem? Please let me know if you need more information/code!

Declare the reference as a member variable:
private TextView text;
Instantiate it in OnCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.wordtoanswer);
//...
}

Related

Is it okay to call MutableLiveData's setValue's method rapildy?

I have an EditText where I need to hold its value in a MutableLiveData in a viewmodel.
Is it okay to be calling the method setValue("the changed edittext string") every time the user edits something in the EditText?
The reason why I'm doing this is to keep the data alive even if the user for example rotated the screen.
Is there any other way to achieve the same result? Cause I feel like it can be expensive and it's a bad practice calling the method over and over. here's an example in an activity:
public class NoteActivity extends AppCompatActivity {
private ActivityNoteBinding binding;
private NoteViewModel viewmodel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_note);
viewmodel = new ViewModelProvider(this).get(NoteViewModel.class);
addObservers();
addListeners();
}
private void addObservers() {
viewmodel.noteBodyLiveData.observe(this, s -> binding.noteBody.setText(s));
}
private void addListeners() {
binding.noteBody.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) {
viewmodel.noteBodyLiveData.setValue(String.valueOf(s));
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
The LiveData Objects are initialized with the data corresponding to what's in the database.
Thanks in advance!

Show the Listview only when the search string is entered

I want the listView to be displayed only when a search string is inserted in the EditText. Below is my code...Please help me I would be highly obliged...
public class MainActivity extends AppCompatActivity {
private ListView mSearchNFilterLv;
private EditText mSearchEdt;
private ArrayList<String> mStringList;
private ValueAdapter valueAdapter;
private TextWatcher mSearchTw;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
initData();
valueAdapter = new ValueAdapter(mStringList, this);
mSearchNFilterLv.setAdapter(valueAdapter);
mSearchEdt.addTextChangedListener(mSearchTw);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
private void initData() {
mStringList = new ArrayList<String>();
mStringList.add("one");
mStringList.add("two");
mStringList.add("three");
mStringList.add("four");
mStringList.add("five");
mStringList.add("six");
mStringList.add("seven");
mStringList.add("eight");
mStringList.add("nine");
mStringList.add("ten");
mStringList.add("eleven");
mStringList.add("twelve");
mStringList.add("thirteen");
mStringList.add("fourteen");
mSearchTw = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
valueAdapter.getFilter().filter(s);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
if(mSearchEdt.getVisibility() != View.VISIBLE)
mSearchEdt.setVisibility(View.VISIBLE);
}
};
}
private void initUI() {
mSearchNFilterLv = (ListView) findViewById(R.id.list_view);
mSearchEdt = (EditText) findViewById(R.id.txt_search);
}
}
You can use the code below:
mSearchTw = 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 != null && s.toString().trim().length() > 0) {
mSearchNFilterLv.setVisibility(View.VISIBLE);
} else {
mSearchNFilterLv.setVisibility(View.GONE);
}
}
#Override public void afterTextChanged(Editable s) {
}
};
This will show the ListView when there is an entered text (while entering text to EditText) and if text has 1 or more characters.
If you want ListView to be changed only when the insertion is over move the given code inside onTextChanged to afterTextChanged
PS: You can use the same structure with SearchView instead of EditText with query listeners.
Updated
You can use below code to hide ListView initially:
private void initUI() {
mSearchNFilterLv = (ListView) findViewById(R.id.list_view);
mSearchEdt = (EditText) findViewById(R.id.txt_search);
mSearchNFilterLv.setVisibility(View.GONE);
}

EditText aftertextchanged throw StackOverflowError

I have an EditText and a TextWatcher. while testing in our test device we never found StackOverflowError, but once we published our app in Google Play Store, we are getting StackOverflowError issue for some user. Why this is happening, I go through some of link but not got the perfect answer. Is anything need to be done in my code.
Skeleton of my code:
weightEditText.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) {
m_currentWeight = weightEditText.getText().toString();
}
#Override
public void afterTextChanged(Editable s)
{
if(!weightEditText.getText().toString().equals("")) {
Pattern mPattern = Pattern.compile("^([1-9][0-9]{0,2}(\\.[0-9]{0,2}?)?)?$");
Matcher matcher = mPattern.matcher(s.toString());
if (!matcher.find()) {
weightEditText.setText(m_currentWeight);
weightEditText.setSelection(weightEditText.getText().length());
}
}
}
});
To avoid recursion here you need to unregister your textWatcher before setting the text and then reregister it.
Declare the TextWatcher outside the addTextChangedListener(...) method. Then you can do weightEditText.removeTextChangedListener(mWatcher) and weightEditText.addTextChangedListener(mWatcher)
You are trying to call setText() inside of the text watcher which will produce an infinite loop. You can use a flag variable to avoid this.
status variable is set as false by defaut.
status variable indicates whether the TextChange is made by App itself or by the user himself. if it is true, then the TextChange is made by App itself and vice versa.
Try this code. Cheers ! :)
public class MainActivity extends AppCompatActivity {
boolean status=false;//global variable
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
weightEditText.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) {
m_currentWeight = weightEditText.getText().toString();
}
#Override
public void afterTextChanged(Editable s)
{
if(status){
status=false;
return;
}else{
status=true;
if(!weightEditText.getText().toString().equals("")) {
Pattern mPattern = Pattern.compile("^([1-9][0-9]{0,2}(\\.[0-9]{0,2}?)?)?$");
Matcher matcher = mPattern.matcher(s.toString());
if (!matcher.find()) {
weightEditText.setText(m_currentWeight);
weightEditText.setSelection(weightEditText.getText().length());
}
}
}
}
});
}
}

Why cant I call method inside Fragment

Why is it not possible to call the checkButtonAddmethod in my Fragment?
public class AddDataFragment extends Fragment {
DbHelper mydb;
Button buttonadd;
Button buttondelete;
private EditText inputLabel;
//Validator boolean
public boolean labelOk;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_add_data, container, false);
final Context context = getContext();
mydb = new DbHelper(context);
[...]
//Label
inputLabel = (EditText) view.findViewById(R.id.editText_label);
inputLabel.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) {
Pattern p = Pattern.compile("^[A-Z]{3}-[0-9]{4}$");
Matcher m = p.matcher(s);
labelOk = m.find();
Log.d("ButtonAdd?", String.valueOf(labelOk));
}
checkButtonAdd(); // <---------------
});
[...]
return view;
}
public void checkButtonAdd(){
if (labelOk){
buttonadd.setEnabled(true);
}else{
buttonadd.setEnabled(false);
}
};
}
I thought this should work because I used it in another Application. But in the MainActivitiy could this be the mistake and if yes, how can I solve it?
You have to call that method from one of the callback methods using this keyword, to get the instance of enclosing Fragment. For instance..
#Override
public void afterTextChanged(Editable s) {
// Your Statements
AddDataFragment.this.checkButtonAdd();
}
No need to declare the method as static. In fact, declaring it static will be a piece of poor code
You are not in the right scope.
Try
AddDataFragment.checkButtonAdd();
instead.

count a particular character in runtime in android

I want to restrict the user to put more than 4 period(.) in a edit text.
how to do this. please any body help
Please make use of following code.
public class Help extends Activity {
public static int count = 0;//use this to check is there are more that 4 '.' char
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((EditText)findViewById(R.id.EditText01)).addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if(count>=4){
//don't allow to right text
}
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//check here if entered text contains more than 4 '.' character
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
}
Please check for logic i have not tested
Edittext e = (editText)Findviewbyid.....
String t= e.geteditable().gettext(); // check methods
if(s.equals(".") || s.equals("..") || s.equals("...")
{
throw some exception and reset it in the catch block
}
I could understand this from your question. is this what u wanted?
Following script counts all periods, but multiple periods are counted once: ... = ., and preriods at the beginning aren't counted.
String text = ((EditText)findViewById(R.id.yourEditText)).getText().toString();
if(text.matches("\\.*[^\\.]+\\.+[^\\.]+\\.+[^\\.]+\\.+[^\\.]+\\.+.+")){
// 4 or more '.', multiple '..' are counted once
}

Categories

Resources