I am trying to implement my own EditTextPreferenceDialogFragmentCompat. I would like to check if the user enter an IP address in the text field. If it's not the case, the user should not be able to validate the dialog. I have successfully shown my custom PreferenceDialogFragmentCompat, but I cannot save the text value anymore!
public class SettingsActivity extends AppCompatActivity {
public static final String PREF_IP_KEY = "ipDs1242_2";
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
...
*/
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new Preferences()).commit();
}
//A Fragment needs to be a public static class
public static class Preferences extends PreferenceFragmentCompat {
private EditTextPreference mIpModulePref;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(getClass().getSimpleName(), "onCreate() frag Prefrences");
}
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences_app);
Log.e(getClass().getSimpleName(), "onCreateFragment()");
mIpModulePref = findPreference(PREF_IP_KEY);
mIpModulePref.setSummary("Addresse IP : " + mIpModulePref.getText());
mIpModulePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.e(getClass().getSimpleName(), "new pref saved"); //never called...
return true;
}
});
mIpModulePref.setOnBindEditTextListener(this);
}
//shows my custom dialog
#Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getFragmentManager().findFragmentByTag(DialogPreferenceFragment.TAG) != null) {
return;
}
if (preference instanceof EditTextPreference && preference.getKey().equals(PREF_IP_KEY)) {
DialogPreferenceFragment dialogPreferenceFragment = DialogPreferenceFragment.newInstance(PREF_IP_KEY);
dialogPreferenceFragment.setTargetFragment(this, DialogPreferenceFragment.REQUEST_CODE);
dialogPreferenceFragment.show(getFragmentManager(), DialogPreferenceFragment.TAG);
} else {
super.onDisplayPreferenceDialog(preference);
}
}
}
//the custom dialog to show
public static class DialogPreferenceFragment extends EditTextPreferenceDialogFragmentCompat {
public static final int REQUEST_CODE = 0;
public static final String TAG = "DialogPreferenceFragment_tag";
private Context mContext;
private EditTextPreference mEditTextPreference;
private SharedPreferences prefs;
public static DialogPreferenceFragment newInstance(String key){
Bundle bundle = new Bundle();
bundle.putString(ARG_KEY, key);
DialogPreferenceFragment dialogPreferenceFragment = new DialogPreferenceFragment();
dialogPreferenceFragment.setArguments(bundle);
return dialogPreferenceFragment;
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
mContext = context;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
}
#Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
Log.e(getClass().getSimpleName(), "restore pref IP");
mEditTextPreference = ((EditTextPreference) getPreference());
String txtValue = prefs.getString(mEditTextPreference.getKey(), ""); //reads the right value
mEditTextPreference.setText(txtValue);
}
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setMessage("Enter the IP address");
}
#Override
public void onDialogClosed(boolean positiveResult) {
if(positiveResult){
Log.e(getClass().getSimpleName(), "save pref IP");
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(mContext).edit();
editor.putString(mEditTextPreference.getKey(), mEditTextPreference.getText());
editor.commit();
String value = prefs.getString(mEditTextPreference.getKey(), ""); //DOESN'T SAVE THE VALUE !
Log.e(getClass().getSimpleName(), value);
}
}
}
}
I can read the right value in the the onBindDialogView() function, but I cannot save my value.
Do you have an idea of what I missed?
Thank you for your help.
Related
This question already has answers here:
How can I change language of whole application by only single click?
(3 answers)
Closed 2 years ago.
I want to change the Language of Application through strings.
here is my string folders
I want to change the Language of Application through strings.
So here is from my side. its works perfectly for me.
Follow these steps to change Language.
1.Save your strings in folder like values-ur(URDU)
than convert your all strings to that language you have to convert
2.Make a BaseActivity class and extend all your rest Activities to that Base class
public class BaseActivity extends AppCompatActivity
{
public BaseActivity context;
public MySharePreference mySharePreference;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context = BaseActivity.this;
mySharePreference = MySharePreference.getInstance(context);
LocaleHelper.setLocale(context, mySharePreference.getLanguage() );
}
protected void attachBaseContext(Context base)
{
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}
3.I have ExampleActivity that i want to translate its language.
public class ExampleActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
}
}
simply extend your application to your BaseActivity class.
3.Make a LocalHelper class in which it change the direction and strings.
public class LocaleHelper
{
public static Context setLocale(Context context, String language)
{
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = new Configuration(resources.getConfiguration());
configuration.setLayoutDirection(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
configuration.setLocale(locale);
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
configuration.setLocales(localeList);
}
else
{
configuration.locale = locale;
configuration.setLocale(locale);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1)
{
return context.createConfigurationContext(configuration);
}
else
{
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
public static Context onAttach(Context context)
{
return setLocale(context, MySharePreference.getInstance(context).getLanguage());
}
}
4.In your App class attach base context
public class AppClass extends MultiDexApplication
{
private static AppClass appClass;
public static AppClass getintance()
{
return appClass;
}
#Override
public void onCreate()
{
super.onCreate();
appClass = this;
MySharePreference.getInstance(this);
}
#Override
protected void attachBaseContext(Context base)
{
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}
5.In your build.gradle file add latest androidx SharedPreferences dependency.
implementation 'androidx.preference:preference:1.1.1'
6.In my case i make my Own SharedPreferences class.
public class MySharePreference
{
private static MySharePreference instance;
private static SharedPreferences pref;
private MySharePreference(Context context)
{
if (context != null)
{
pref = PreferenceManager.getDefaultSharedPreferences(context);
}
else
{
pref = PreferenceManager.getDefaultSharedPreferences(App.getintance());
}
}
public static MySharePreference getInstance(Context context)
{
if (instance == null || pref == null)
{
instance = new MySharePreference(context);
}
return instance;
}
public String getLanguage()
{
return pref.getString("appLanguage", "en");
}
public void setLanguage(String b)
{
pref.edit().putString("appLanguage", b).apply();
}
}
7.At last save the abbreviation of that language to SharedPreferences in my case i have spinner.
spinner_lang.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
if (mySharePreference.getLanguagePosition() != position)
{
mySharePreference.setLanguage(Constants.COUNTRY_LIST.get(position).countryAbbr);
mySharePreference.setLanguagePosition(position);
startActivity(new Intent(mActivity, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
}
#Override
public void onNothingSelected(AdapterView<?> parent)
{
}
});
now all done......
I created a day/night mode switch system in my app. Currently, I use a PreferenceFragmentCompat + SharedPreference to display and save the switch selection.
This is my code:
public class PreferencesActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preferences);
PreferencesFragment preferencesFragment = new PreferencesFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.preferences_container, preferencesFragment).commit();
}
public static class PreferencesFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
}
#Override
public void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (isAdded()) {
if (sharedPreferences.getBoolean(getString(R.string.KEY_PREF_NIGHT_MODE), false)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
}
}
}
On top of that, I use the following code in the OnCreate method of my main Activity:
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
int mode = sharedPreferences.getBoolean(getString(R.string.KEY_PREF_NIGHT_MODE), false) ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO;
if (AppCompatDelegate.getDefaultNightMode() != mode)
AppCompatDelegate.setDefaultNightMode(mode);
The problem is that when I activate the dark mode and I restart the application, it will launch then restart in the onCreate. Isn't there a more optimal way to implement this system?
you could create BaseActivity where you set the night mode
abstract class BaseActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
}
}
and then extend all your Activites from BaseActivity
public class PreferencesActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
}
then your night mode would be set in every activity before setContentView and no relaunch would be occured
UPDATE
change
#Override
public void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
to
#Override
public void onStart() {
super.onStart();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
onStart is called before view is visible
UPDATE 2
here is the singleton to access SharedPreferences
public class SharedManager {
private static SharedManager instance;
private final SharedPreferences preferences;
private SharedManager() {
preferences = MyApplication.getAppContext().getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
}
public static SharedManager getInstance() {
if (instance == null) {
synchronized (SharedManager.class) {
if (instance == null) {
instance = new SharedManager();
}
}
}
return instance;
}
public SharedPreferences getPreferences() {
return preferences;
}
}
with call SharedManager.getInstance().getPreferences() you can get access to Preferences
I'm getting nullPointerException when I try to set data to textviews from the JSON response,I'm getting through retrofit. I would like to set the total sale, total expense and total purchase values to the textviews:
tv_total_purchase_today,
tv_total_sale_today,
tv_total_expense_today
What should I put in the setsaleInformations method?
Here's my code:
API Response
public class DashboardResponse extends CommonResponse {
#Expose
#SerializedName("graph_data")
private ArrayList<Graph> graph_data;
#Expose
#SerializedName("total_sale")
private String total_sale;
#Expose
#SerializedName("total_purchase")
private String total_purchase;
#Expose
#SerializedName("total_expense")
private String total_expense;
public ArrayList<Graph> getGraph_data() {
return graph_data;
}
public void setGraph_data(ArrayList<Graph> graph_data) {
this.graph_data = graph_data;
}
public String getTotal_sale() {
return total_sale;
}
public void setTotal_sale(String total_sale) {
this.total_sale = total_sale;
}
public String getTotal_purchase() {
return total_purchase;
}
public void setTotal_purchase(String total_purchase) {
this.total_purchase = total_purchase;
}
public String getTotal_expense() {
return total_expense;
}
public void setTotal_expense(String total_expense) {
this.total_expense = total_expense;
}
}
API Interactor Implementation
#Override
public void getDashboard(final DashboardListener dashboardListener) {
Call<DashboardResponse> call = apiServiceInterface.getDashboard();
call.enqueue(new Callback<DashboardResponse>() {
#Override
public void onResponse(Call<DashboardResponse> call, Response<DashboardResponse> response) {
if(isResponseValid(response) && response.body().isSuccess()){
dashboardListener.onDashboardFetch(response.body());
}else{
dashboardListener.onFailed(prepareFailedMessage(response), APIConstants.DASHBOARD);
}
}
Dashboard Fragment
public class DashboardFragment extends Fragment {
private Context context;
private SalesUtils salesUtils;
private DashboardResponse dashboardResponse;
private HomePresenter homePresenter;
private HomeView homeView;
#BindView(R.id.tv_total_sale_today)
TextView tv_total_sale_today;
#BindView(R.id.tv_total_purchase_today)
TextView tv_total_purchase_today;
#BindView(R.id.tv_total_expense_today)
TextView tv_total_expense_today;
#BindView(R.id.cv_sale_today)
CardView cv_sale_today;
#BindView(R.id.cv_purchase_today)
CardView cv_purchase_today;
#BindView(R.id.cv_expense_today)
CardView cv_expense_today;
private ArrayList<Sale> salesToday;
private ArrayList<Product> productSoldToday;
private SimpleDateFormat simpleDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault());
public DashboardFragment() {
// Required empty public constructor
}
public static DashboardFragment newInstance(HomePresenter homePresenter) {
DashboardFragment fragment = new DashboardFragment();
fragment.initializeSaleInfo(homePresenter);
return fragment;
}
private void initializeSaleInfo(HomePresenter homePresenter) {
this.homePresenter = homePresenter;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getActivity();
homeView = (HomeView) getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_dashboard, container, false);
ButterKnife.bind(this, rootView);
cv_sale_today.startAnimation(AnimationUtils.loadSlideInLeftAnimation(context));
cv_purchase_today.startAnimation(AnimationUtils.loadFadeInAnimation(context));
cv_expense_today.startAnimation(AnimationUtils.loadSlideInRightAnimation(context));
homePresenter.fetchDashboard();
setListeners();
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
if(homeView!=null) {
homeView.changeSearchState(false);
}
}
#Override
public void onPause() {
super.onPause();
if(homeView != null)
homeView.setIsInSaleInfo(false);
}
public void setSaleInformations() {
if (getActivity() != null && isAdded())
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
tv_total_purchase_today.setText();
tv_total_sale_today.setText();
tv_total_expense_today.setText();
}
});
}
private Thread resumeSaleInfo = new Thread(new Runnable() {
#Override
public void run() {
salesToday = salesUtils.getSalesDuring(ApplicationUtils.getStartingDateTime(simpleDateTimeFormat.format(System.currentTimeMillis())), ApplicationUtils.getEndingDateTime(simpleDateTimeFormat.format(System.currentTimeMillis())));
if (getActivity() != null && isAdded())
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
tv_total_purchase_today.setText(ApplicationUtils.getBengaliNumber(salesToday.size() + "") + " " + getString(R.string.buy_today_label));
tv_total_sale_today.setText(ApplicationUtils.currencyFormat(SalesUtils.getTotalSale(salesToday)));
tv_total_expense_today.setText(ApplicationUtils.getBengaliNumber(SalesUtils.countUnitSold(productSoldToday) + "") + " " + getString(R.string.unit_sold));
}
});
}
});
private void setListeners() {
cv_sale_today.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homePresenter.showSaleAt(simpleDateTimeFormat.format(System.currentTimeMillis()));
}
});
cv_purchase_today.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homePresenter.showSaleAt(simpleDateTimeFormat.format(System.currentTimeMillis()));
}
});
cv_expense_today.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
homePresenter.showUnitSold(simpleDateTimeFormat.format(System.currentTimeMillis()), simpleDateTimeFormat.format(System.currentTimeMillis()));
}
});
}
public void setDashboard(DashboardResponse dashboardResponse) {
Log.e("DASHBOARD", new Gson().toJson(dashboardResponse));
this.dashboardResponse = dashboardResponse;
setSaleInformations();
}
}
That means either the text views haven't loaded onto the screen yet or the views haven't been initialized yet.
what's a good way to show current value of SeekBarPreference into ScreenPreference.
I've tried to insert textview but the app crashes.
Any suggestions?
preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SeekBarPreference
android:id="#+id/seekbar_pref"
android:key="seekbar_x"
android:title="Value"
android:defaultValue="1"
android:max="60"/>
</PreferenceScreen>
Preferences.java
public class Preferences extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
Main.java
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.e("SHARED", "VAL: " + sharedPreferences.getInt("seekbar_x",10));
}
};
In your onCreate method add this line at the end (after adding preferences):
SeekBarPreference pref = (SeekBarPreference) findPreference("seekbar_pref");
Then add the listener on it like this:
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int value = mSeekBarPreference.getProgress(); //or (int) newValue
//You can now use this value wherever you like:
pref.setSummary("Value: " + value);
return true;
}
});
I have the following fragment.The problem is that every time I launch this the app crashes with the following exception : attempt to invoke virtual method android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext() on a null object reference. From what I understand getActivity is called correctly, however the FragmentActivityTesting does not return any context, I'm not sure why this is the case:
public class FragmentATesting extends Fragment {
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle SavedInstanceState) {
super.onCreate(SavedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_a,container,false);
}
#Override
public void onActivityCreated(Bundle SavedInstanceState){
super.onActivityCreated(SavedInstanceState);
}
#Override
public void onStart() {
super.onStart();
final SessionManager session = new SessionManager(getActivity().getApplicationContext());
TextView username = (TextView) getView().findViewById(R.id.username_info_txt);
HashMap<String,String> userString = session.getUserDetails();
String usernamee = userString.get("username");
username.setText(usernamee);
vote(usernamee);
}
#Override
public void onResume() {
super.onResume();
final SessionManager session = new SessionManager(getActivity().getApplicationContext());
TextView username = (TextView) getView().findViewById(R.id.username_info_txt);
HashMap<String,String> userString = session.getUserDetails();
String usernamee = userString.get("username");
username.setText(usernamee);
vote(usernamee);
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
#Override
public void onDestroy() {
super.onDestroy();
}
private void vote(final String userId) {
class UploadImage extends AsyncTask<String, Void, String> {
RequestHandler rh = new RequestHandler();
#Override
protected String doInBackground(String... params) {
HashMap<String, String> data = new HashMap<>();
data.put("username",userId);
String result = rh.sendPostRequest(SL_URL2, data);
return result;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
JSONObject jsonObject = null;
String likess = "";
try {
jsonObject = new JSONObject(s);
} catch (JSONException e) {
e.printStackTrace();
}
try {
likess = jsonObject.getString("amount");
} catch (JSONException e) {
e.printStackTrace();
}
TextView amount = (TextView) getView().findViewById(R.id.likes_info_txt);
amount.setText(likess + " Likes");
}}
UploadImage ui = new UploadImage();
ui.execute();
}`
It is inside my ViewPager defined as follows:
public class FragmentActivityTesting extends FragmentActivity {
ViewPager viewPager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_activity_testing);
viewPager = (ViewPager) findViewById(R.id.pic_pager);
setStatusBarColor();
FragmentManager fragmentManager = getSupportFragmentManager();
viewPager.setAdapter(new MyAdapter(fragmentManager));
viewPager.setCurrentItem(1);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CLOSE_ALL");
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
#TargetApi(21)
public void setStatusBarColor() {
Window window = this.getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 21) {
window.setStatusBarColor(this.getResources().getColor(R.color.green));
}
}}
class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position ==0) {
fragment = new FragmentATesting();
}
else if (position == 1) {
fragment = new FragmentBTesting();
}
else if (position == 2) {
fragment = new FragmentCTesting();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
}