Calling SharedPrefences in Fragments - android-studio

I have a class with the name of SharePrefManager. Here is the code
package com.example.lms02;
public class SharedPrefManager {
private static final String SHARED_PREF_NAME = "volleyregisterlogin";
private static final String KEY_USERNAME = "keyusername";
private static final String KEY_EMAIL = "keyemail";
private static final String KEY_GENDER = "keygender";
private static final String KEY_ID = "keyid";
private static final String KEY_STDID = "keystdid";
private static final String KEY_USER_STATUS = "keyuserstatus";
private static SharedPrefManager mInstance;
private static Context ctx;
private SharedPrefManager(Context context) {
ctx = context;
}
public static synchronized SharedPrefManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new SharedPrefManager(context);
}
return mInstance;
}
//this method will store the user data in shared preferences
public void userLogin(User user) {
SharedPreferences sharedPreferences = ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(KEY_ID, user.getId());
editor.putString(KEY_STDID,user.getStdid());
editor.putString(KEY_USERNAME, user.getName());
editor.putString(KEY_EMAIL, user.getEmail());
editor.putString(KEY_GENDER, user.getGender());
editor.putString(KEY_USER_STATUS, user.getStatus());
editor.apply();
}
//this method will checker whether user is already logged in or not
public boolean isLoggedIn() {
SharedPreferences sharedPreferences = ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(KEY_USERNAME, null) != null;
}
//this method will give the logged in user
public User getUser() {
SharedPreferences sharedPreferences = ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
return new User(
sharedPreferences.getInt(KEY_ID, -1),
sharedPreferences.getString(KEY_STDID, null),
sharedPreferences.getString(KEY_USERNAME, null),
sharedPreferences.getString(KEY_EMAIL, null),
sharedPreferences.getString(KEY_GENDER, null),
sharedPreferences.getString(KEY_USER_STATUS, null)
);
}
//this method will logout the user
public void logout() {
SharedPreferences sharedPreferences = ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.apply();
ctx.startActivity(new Intent(ctx, LoginActivity.class));
}
}
I am using Fragments. Here is the code of my Fragment
public class HomeFragment extends Fragment {
TextView txtvwuserid;
User user = SharedPrefManager.getInstance(getContext()).getUser();
public HomeFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
txtvwuserid = getActivity().findViewById(R.id.txtvwstdid);
txtvwuserid.setText("Hy");
}
}
The problem occurs in HomeFragment here
User user = SharedPrefManager.getInstance(getContext()).getUser();
The Error shown is:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences
android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
My Problem is how can i access the values of SharedPrefManager and what does the error means

Problem Solved:
According to the Fragment Life Cycle. we have to place all of our code after the creation of Fragment. What I was doing wrong is Declaring the User object before creation of fragment. Placing it like
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
user = SharedPrefManager.getInstance(getActivity()).getUser(); //Placing here
}
It Worked For me. Cheers...!!!

Related

Cannot infer arguments (unable to resolve constructor)

I am trying to make a program with a tablayout, each tab representing a fragment. In the second fragment (AddFragment), im want to make a list that displays the strings I entered in the EditText. But its giving me the error above. More detailed:
error: cannot infer type arguments for ArrayAdapter<>
itemsAdapter = new ArrayAdapter<>(AddFragment.this, android.R.layout.simple_list_item_1, items);
Code for the AddFragment class:
public class AddFragment extends Fragment {
EditText etPlan;
EditText etExercise;
ImageButton imageButton;
ArrayList<String> items;
ArrayAdapter<String> itemsAdapter;
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_add, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
findViews();
super.onViewCreated(view, savedInstanceState);
}
private void findViews() {
listView = getView().findViewById(R.id.listView);
etPlan = getView().findViewById(R.id.etPlan);
etExercise = getView().findViewById(R.id.etExercise);
imageButton = getView().findViewById(R.id.imageButton);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
items = new ArrayList<>();
itemsAdapter = new ArrayAdapter<>(AddFragment.this, android.R.layout.simple_list_item_1, items);
listView.setAdapter(itemsAdapter);
setUpListViewListener();
}
private void setUpListViewListener() {
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Context context = getContext();
Toast.makeText(context, "Item Removed", Toast.LENGTH_LONG).show();
items.remove(position);
itemsAdapter.notifyDataSetChanged();
return true;
}
});
}
});
}
}
The declaration that you have works if working directly in the activity JAVA file. While working in the fragment, you need to establish clearly the type of argument and provide the correct context.
The following should work (assuming that you are passing strings):
itemsAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);

how to pass data from activity to java class in android

i want to pass some data from activity to a java class i use intent to pass data from activity to a java class .
// Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_workspace);
worklink = findViewById(R.id.workspace);
button = findViewById(R.id.continu);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String work_link = worklink.getText().toString().trim();
SharedPreferences sharedPref = getSharedPreferences("myKey", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("value", work_link);
editor.apply();
Intent intent = new Intent(workspace.this,BaseURL.class);
startActivity(intent);
}
});
// java class
import android.content.Intent;
public class BaseURL {
String value = getIntent.getExtra("worklink");
}
Create a Global class and create getter setter then set the data you want to pass
public class GlobalData {
public static String status;
public static int getStatus() {
return status;
}
public static void setStatus(String status) {
GlobalData.status = status;
}
}

RecycleView adapter and main code is not working by an unknown mistake, can you spot the diffrence

hello everyone, I am kind of new using android studio and I am working on my school project. I need to use RecycleVie wand I tried making it but without success.
I use a Object class caled Task whcih have 3 propeties to be shown on the layout but I don't know where is my mistake. the rows which shown as problems are in bold. I will be glad if anyone can help me!
my Object class:
public class Task {
private String material;
private String day;
private String month;
public Task (String material,String day,String month)
{
this.material = material;
this.day = day;
this.month = month;
}
public String getMaterial() {
return material;
}
public void setMaterial(String material) {
this.material = material;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
}
the Adapter Code:
public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerViewAdapter.ViewHolder> {
private Context mCtx;
private List<Task> tList;
// data is passed into the constructor
public HomeRecyclerViewAdapter(Context mCtx, List<Task> tList) {
this.mCtx = mCtx;
this.tList = tList;
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvText, tvDateDay, tvDateMonth;
public ViewHolder(View itemView) {
super(itemView);
tvText = itemView.findViewById(R.id.tvText);
tvDateDay = itemView.findViewById(R.id.tvDateDay);
tvDateMonth = itemView.findViewById(R.id.tvDateMonth);
}
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.home_recyclerview_row, null);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Task task = tList.get(position);
**holder.tvText.setText(task.getMaterial());**
}
// allows clicks events to be caught
#Override
public int getItemCount() {
return tList.size();
}
}
and the main code:
public class HomeScreen_activity extends AppCompatActivity implements View.OnClickListener {
List<Task> tList;
RecyclerView homercy;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.home_screen_layout);
homercy = (RecyclerView) findViewById(R.id.homercy);
homercy.setHasFixedSize(true);
homercy.setLayoutManager(new LinearLayoutManager(this));
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.homercy);
tList = new ArrayList<Task>();
Task t1 = new Task("test","12","05");
tList.add(t1);
**HomeRecyclerViewAdapter adapter = new HomeRecyclerViewAdapter(this,tList);**
recyclerView.setAdapter(adapter);
}
Maybe in onCreateViewHolder(), you must do this:
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_recyclerview_row, parent, false);
return new ViewHolder(view);
}

Tracking selected tab and changing a textview accordingly

I'm working on my 1st android project, which uses a tab layout. I want to keep track of the active tab and change a textview present in the appbar (main activity).
Here is my main activity, tab manager, and a fragment
MAIN ACTIVITY
private static final String TAG = "MainActivity";
private SectionsPageAdapter mSectionsPageAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPageAdapter = new SectionsPageAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.Tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.tab_rooms_24dp);
tabLayout.getTabAt(1).setIcon(R.drawable.tab_feed_24dp);
tabLayout.getTabAt(2).setIcon(R.drawable.tab_profile_24dp);
tabLayout.getTabAt(0).getIcon().setColorFilter(getResources().getColor(R.color.Accent), PorterDuff.Mode.SRC_IN);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
tab.getIcon().setColorFilter(getResources().getColor(R.color.Accent),PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.getIcon().clearColorFilter();
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void setupViewPager(ViewPager viewPager){
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(), "");
adapter.addFragment(new Tab2Fragment(), "");
adapter.addFragment(new Tab3Fragment(), "");
viewPager.setAdapter(adapter);
}
TAB MANAGER
private final List<Fragment> mFragmentList =new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title );
}
public SectionsPageAdapter(FragmentManager fm) {
super(fm);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
FRAGMENT
private static final String TAG = "Tab3Fragment";
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab1,container,false);
return view;
}
I tried creating a variable in an abstract class then extending it into all three of these scripts which would be a simple solution but fragments dont seem to work well with extending, not to mention that probably isnt the most efficient method.
So I'm thinking the best method would be to simply handle it from the SectionsPageManager script?
Use addOnPageChangeListener on you pager.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 1) {
setTitle("Tab 1");
} else if (position == 2)
{
setTitle("Tab 2");
}
else
{
setTitle("Home");
}
}
So I got it worked out and figured I'd come post the answer for anyone who may need it.
Not that the above answer sets the app title, not a TextView withing the appbar as stated in the question.
private static final String TAG = "MainActivity";
private SectionsPageAdapter mSectionsPageAdapter;
private ViewPager mViewPager;
private TextView activeTab;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activeTab = (TextView)findViewById(R.id.PageTitle);
mSectionsPageAdapter = new SectionsPageAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
}
private void setupViewPager(ViewPager viewPager)
{
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(), "");
adapter.addFragment(new Tab2Fragment(), "");
adapter.addFragment(new Tab3Fragment(), "");
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
#Override
public void onPageSelected(int position)
{
switch (position){
case 0: activeTab.setText("text");
break;
case 1: activeTab.setText("better text");
break;
case 2: activeTab.setText("best text");
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}

How to implement onActivityResult within RecyclerView Fragment

I am trying to have a button within a Tab which is part of an activity for uploading images, when clicking the button inside one of the 2 Tabs presented in the activity ( Tab 1 pics, Tab 2 Vid ) the user could choose an image from the device.
My problem is implemneting the onClick Listener and onActivityResult which is not being used when placed after onClick, plus the #Override is being underlined as an error.
I guess i am not implementing the onClick the right way and not sure how to activate onActivityResult the proper way, i would appreciate any guidance;
MainActivty;
public class upload extends AppCompatActivity {
public String UserID;
private static final int REQUEST_SIGNUP = 0;
private DrawerLayout mDrawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.upload);
Firebase.setAndroidContext(this);
// Adding Toolbar to Main screen
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Setting ViewPager for each Tabs
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Set Tabs inside Toolbar
TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new UploadPictures(), "Pictures");
adapter.addFragment(new UploadVideos(), "Videos");
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
And here is the Fragment Code;
public class UploadPictures extends android.support.v4.app.Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final RecyclerView recyclerView = (RecyclerView) inflater.inflate(
R.layout.recycler_view, container, false);
ContentAdapter adapter = new ContentAdapter(recyclerView.getContext());
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView picture;
public EditText tagEditText;
public Button tagCurLoc, choosePic, uploadContent;
public ViewHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.pictue_upload, parent, false));
picture = (ImageView) itemView.findViewById(R.id.imgToUpload);
tagEditText = (EditText) itemView.findViewById(R.id.tagEditText);
tagCurLoc = (Button) itemView.findViewById(R.id.tagCurLoc);
choosePic = (Button) itemView.findViewById(R.id.choosePic);
choosePic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
onActivityResult(requestCode, resultCode, data);
Toast.makeText(getActivity().getApplicationContext(), "Canceled ", Toast.LENGTH_SHORT).show();
} else {
if (requestCode == RESULT_LOAD_IMAGE) {
Uri selectedImgPath = data.getData();
picture.setImageURI(selectedImgPath);
RealFilePath = Uri.parse(String.valueOf(selectedImgPath));
Toast.makeText(getActivity().getApplicationContext(), " " + RealFilePath, Toast.LENGTH_SHORT).show();
}
}
}
});
uploadContent = (Button) itemView.findViewById(R.id.uploadContent);
}
}
/**
* Adapter to display recycler view.
*/
public class ContentAdapter extends RecyclerView.Adapter<ViewHolder> {
// Set numbers of List in RecyclerView.
private Context mContext;
public ContentAdapter(Context context) {
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return LENGTH;
}
}
Not sure if the onClick listener for the button should be implemented in the Adapter or the View holder, and from there the issue of onActivityResult cant be used ?
Weel, solved after some more reading and few try outs.
The onClick listener should be implemented at the ViewHolder class followed by
#Override
onActivityResult.
within the onClickListener onActivityResult invoked by;
startActivityForResult(intent, RESULT_LOAD_IMAGE);
and within onActivityResult;
onActivityResult(requestCode, resultCode, data);
Considering all of this taking place in an activity extending Fragment.

Resources