I'm new to Android and I started building a "Navigation Drawer Activity" project. I added a TabLayout and ViewPager to my activity_main.xml and now I can swipe between different lists. When I click an item in a list, it calls onListFragmentInteraction in my MainActivity.java. I tried the code below to dynamically add a Detail fragment when a user clicks an item in the list, but I get this error. My MainActivity class does "implement CustomerFragment.OnListFragmentInteractionListener"
First, is my attempt at showing a detail fragment inside a ViewPager correct? Would the code I am attempting below add a fragment in the current tab?
Secondly, does anyone know why I am getting this error?
Thanks so much!
Error:
java.lang.RuntimeException: com.myproject.android.MainActivity#186e12d
must implement OnFragmentInteractionListener
MainActivity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, TabLayout.OnTabSelectedListener, CustomerFragment.OnListFragmentInteractionListener, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private TabLayout tabLayout;
private ViewPager viewPager;
private Pager adapter;
public void onListFragmentInteraction(Customer customer){
FragmentManager fm = getSupportFragmentManager();
CustomerDetailFragment fragment = CustomerDetailFragment.newInstance(customer);
fm.beginTransaction().add(R.id.pager, fragment).commit();
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) { }
#Override
public void onTabReselected(TabLayout.Tab tab) { }
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Home"));
tabLayout.addTab(tabLayout.newTab().setText("Customers"));
tabLayout.addTab(tabLayout.newTab().setText("Jobs"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
tabLayout.addOnTabSelectedListener(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
FirebaseMessaging.getInstance().subscribeToTopic("global");
String token = FirebaseInstanceId.getInstance().getToken();
// Check Google Play Services
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.build();
// test
Date d = new Date();
DbHandler dbHandler = new DbHandler(this, null, null, 1);
Customer customer = new Customer(1, 1, 1, 1, "Test", "Test", "Test", false, d, 1, d, 1);
dbHandler.addCustomer(customer);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
startActivity(new Intent(this, LoginActivity.class));
} else if (id == R.id.nav_gallery) {
startActivity(new Intent(this, SyncActivity.class));
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
Customer List Fragment:
public class CustomerFragment extends Fragment {
private OnListFragmentInteractionListener mListener;
public CustomerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_customer_list, container, false);
SearchView sv = (SearchView) view.findViewById(R.id.searchview);
RecyclerView rv = (RecyclerView) view.findViewById(R.id.recyclerview);
// Adapter
rv.setLayoutManager(new LinearLayoutManager(view.getContext()));
final CustomerAdapter adapter = new CustomerAdapter(getCustomers(), mListener);
rv.setAdapter(adapter);
// Search
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String query) {
//adapter.getFilter().filter(query);
return false;
}
});
return view;
}
private ArrayList<Customer> getCustomers() {
DbHandler dbHandler = new DbHandler(this.getActivity(), null, null, 1);
ArrayList<Customer> customers = dbHandler.getCustomers();
return customers;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement OnListFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnListFragmentInteractionListener {
void onListFragmentInteraction(Customer customer);
}
}
Customer Adapter:
public class CustomerAdapter extends RecyclerView.Adapter<CustomerAdapter.ViewHolder> {
private final List<Customer> mValues;
private final OnListFragmentInteractionListener mListener;
public CustomerAdapter(List<Customer> items, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_customer, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Customer customer = mValues.get(position);
holder.mItem = customer;
holder.mIdView.setText(String.valueOf(customer.getId()));
holder.mContentView.setText(customer.getCompanyName());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (null != mListener) {
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public Customer mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
UPDATE: It looks like I needed to add both onListFragmentInteraction AND onFragmentInteraction. The first is for the CustomerListFragment and the 2nd is for the CustomerDetailFragment.
And to get the CustomerDetailFragment working with the tabs, I followed this and got it working:
https://medium.com/#nilan/separate-back-navigation-for-a-tabbed-view-pager-in-android-459859f607e4#.lrjeexdcp
#Override
public void onListFragmentInteraction(Customer customer){
FragmentManager fm = getSupportFragmentManager();
CustomerDetailFragment fragment = CustomerDetailFragment.newInstance(customer);
fm.beginTransaction().add(R.id.pager, fragment).commit();
}
#Override
public void onFragmentInteraction(Uri uri) {
}
You need to put
public void onListFragmentInteraction(Customer customer){
FragmentManager fm = getSupportFragmentManager();
CustomerDetailFragment fragment = CustomerDetailFragment.newInstance(customer);
fm.beginTransaction().add(R.id.pager, fragment).commit();
}
Inside your MainActivity class instead of outside of it.
If that's not actually how your code is, edit your answer to break up the blocks to accurately represent how your code is built and include your interfance inside the fragment for the listener. You also may need the #Override tag above the onListFragmentInteraction implementation
Edit
As I mentioned above you need to put the #Override tag above the onListFragmentInteraction implementation, look at every other listener implementation you already have.
Related
I have different fragments in my MainActivity. In each fragment I implemented some features.
Now I am trying to implemented tabs for one fragments, what I'm looking for is about hide tab layout in remaining fragments.
activity.xml:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.genworks.oppm.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/activity_search_view_check"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include layout="#layout/toolbar"/>
<include layout="#layout/search_toolbar"
android:visibility="gone"/>
</RelativeLayout>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabIndicatorColor="#color/White"
app:tabTextColor="#color/White"
android:background="#drawable/button_background"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:tabGravity="fill"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
Fragment fragment;
int CAMERA_PIC_REQUEST=20;
Menu search_menu;
MenuItem item_search;
ExpandableListView expListView;
TabLayout tabLayout;
private ProgressDialog progressDialog = null;
TextView user,firstname,lastname,mobile,role,report_to;
String user_name;
ImageView profile;
private ArrayList<Records> records;
private ArrayList<Records> recordsList=new ArrayList<>();
ViewPager viewPager;
TextView mTitle;
private RecyclerView recyclerView;
static final int REQUEST_TAKE_PHOTO = 1;
static final int REQUEST_GALLERY_PHOTO = 2;
File mPhotoFile;
FileCompressor mCompressor;
private RecyclerView.Adapter mAdapter;
String sessionId,username,first_name,last_name,mobile_no,role_id,reportto;
MenuItem refreshMenuItem;
ExpandableListView expandableList;
ExpandableListAdapterMenu mMenuAdapter;
List <ExpandedMenuModel> listDataHeader;
private final Handler handler = new Handler ( );
HashMap <ExpandedMenuModel, List <String>> listDataChild;
private RecyclerView.LayoutManager layoutManager;
private boolean ismenutoggle;
private Toolbar searchtollbar,toolbar;
boolean needLogin = false;
LinearLayout dashboard,taskmenu,account,contact,opportunity,logout,documents;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sessionId = getIntent().getStringExtra("sessionId");
username = getIntent().getStringExtra("username");
PreferenceUtils.getUsername(this);
PreferenceUtils.getPassword(this);
first_name = getIntent().getStringExtra("firstname");
last_name = getIntent().getStringExtra("lastname");
mobile_no = getIntent().getStringExtra("mobile");
role_id = getIntent().getStringExtra("role");
reportto = getIntent().getStringExtra("reportto");
dashboard=findViewById(R.id.dashboard);
taskmenu=findViewById(R.id.taskmenu);
contact=findViewById(R.id.contactmenu);
opportunity=findViewById(R.id.opportunitymenu);
account=findViewById(R.id.accountmenu);
logout=findViewById(R.id.logout);
// user = (TextView) findViewById(R.id.username);
profile=findViewById(R.id.profile);
mCompressor = new FileCompressor(this);
firstname = (TextView) findViewById(R.id.firstname);
lastname = (TextView) findViewById(R.id.lastname);
mobile=findViewById(R.id.mobile);
role=findViewById(R.id.role);
report_to=findViewById(R.id.report_to);
firstname.setText(first_name);
lastname.setText(last_name);
mobile.setText(mobile_no);
role.setText(role_id);
report_to.setText(reportto);
// user.setText(username);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// getSupportActionBar().setTitle("DASHBOARD");
final ActionBar ab = getSupportActionBar();
ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ab.setCustomView(R.layout.toolbar_spinner);
if (ab != null) {
ab.setDisplayShowTitleEnabled(false);
mTitle = (TextView) findViewById(R.id.toolbar_title);
mTitle.setText("DASHBOARD");
mTitle.setGravity(Gravity.CENTER_HORIZONTAL);
// Typeface typeface = Typeface.createFromAsset(getApplicationContext ().getAssets (), "fonts/astype - Secca Light.otf");
// mTitle.setTypeface (typeface);
}
ab.setHomeAsUpIndicator(R.drawable.menu);
ab.setDisplayHomeAsUpEnabled(true);
//ab.setTitle ("HOME");
setSearchtollbar();
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
fragment = new DashboardFragement();
loadFragment(fragment);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
if (navigationView != null) {
setupDrawerContent (navigationView);
}
// TextView dashboard=findViewById(R.id.menu_dashboard);
dashboard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTitle.setText("Dashboard");
fragment = new DashboardFragement();
loadFragment(fragment);
drawerLayout.closeDrawer(GravityCompat.START);
}
});
// TextView task=findViewById(R.id.menu_task);
taskmenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTitle.setText("Task List");
fragment = new TaskFragement();
loadFragment(fragment);
drawerLayout.closeDrawer(GravityCompat.START);
}
});
account.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTitle.setText("Account List");
fragment = new AccountFragement();
loadFragment(fragment);
drawerLayout.closeDrawer(GravityCompat.START);
}
});
contact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTitle.setText("Contact List");
fragment = new ContactFragment();
loadFragment(fragment);
drawerLayout.closeDrawer(GravityCompat.START);
}
});
// TextView opportunity=findViewById(R.id.menu_opportunity);
opportunity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTitle.setText("Opportunity List");
fragment = new SalesStageFragment();
loadFragment(fragment);
drawerLayout.closeDrawer(GravityCompat.START);
}
});
// TextView logout=findViewById(R.id.menu_logout);
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences preferences = getSharedPreferences("login", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.commit();
Intent i = new Intent(MainActivity.this, LoginActivity.class);
startActivity(i);
finish();
drawerLayout.closeDrawer(GravityCompat.START);
}
});
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImage();
}
});
initBottomNavigationItems();
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new TaskFragement(), "All");
adapter.addFragment(new AccountFragement(), "Incomplete");
adapter.addFragment(new ContactFragment(), "Scheduled");
adapter.addFragment(new ContactFragment(), "Today");
adapter.addFragment(new ContactFragment(), "Weekwise");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(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);
}
}
private void selectImage() {
final CharSequence[] items = {"Take Photo", "Choose from Gallery",
"Cancel"};
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(MainActivity.this);
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
MainActivity.this.requestStoragePermission(true);
} else if (items[item].equals("Choose from Gallery")) {
MainActivity.this.requestStoragePermission(false);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
public void initBottomNavigationItems() {
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment;
switch (item.getItemId()) {
case R.id.account:
mTitle.setText("ACCOUNT LIST");
fragment = new AccountFragement();
loadFragment(fragment);
return true;
case R.id.task:
mTitle.setText("TASK LIST");
fragment = new TaskFragement();
loadFragment(fragment);
return true;
case R.id.contact:
mTitle.setText("CONTACT LIST");
fragment = new ContactFragment();
loadFragment(fragment);
return true;
case R.id.opportunity:
mTitle.setText("OPPORTUNITY LIST");
fragment = new SalesStageFragment();
loadFragment(fragment);
return true;
}
return false;
}
});
}
private void loadFragment(Fragment fragment) {
// load fragment
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
menu.findItem(R.id.search).setVisible(false);
return true;
}
private void setupDrawerContent(NavigationView navigationView) {
//revision: this don't works, use setOnChildClickListener() and setOnGroupClickListener() above instead
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
if(menuItem.isChecked ()){
drawerLayout.openDrawer (GravityCompat.START);}
else {
drawerLayout.closeDrawer (GravityCompat.START);
}
return true;
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if(ismenutoggle==true) {
drawerLayout.openDrawer (GravityCompat.START);
ismenutoggle=false;
}
else{
drawerLayout.closeDrawer (GravityCompat.START);
ismenutoggle=true;
}
return true;
}
return super.onOptionsItemSelected(item);
}
private AdapterView.OnItemClickListener mDrawerItemClickedListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
}
};
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
finish();
}
}
private DrawerLayout.DrawerListener mDrawerListener = new DrawerLayout.DrawerListener () {
#Override
public void onDrawerStateChanged(int status) {
}
#Override
public void onDrawerSlide(View view, float slideArg) {
}
#Override
public void onDrawerOpened(View view) {
drawerLayout.openDrawer (view);
}
#Override
public void onDrawerClosed(View view) {
drawerLayout.closeDrawer (view);
}
};
public void setSearchtollbar()
{
searchtollbar = (Toolbar) findViewById(R.id.searchtoolbar);
if (searchtollbar != null) {
searchtollbar.inflateMenu(R.menu.menu_search);
search_menu=searchtollbar.getMenu();
searchtollbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
circleReveal(R.id.searchtoolbar,1,true,false);
else
searchtollbar.setVisibility(View.GONE);
}
});
item_search = search_menu.findItem(R.id.action_filter_search);
MenuItemCompat.setOnActionExpandListener(item_search, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
circleReveal(R.id.searchtoolbar,1,true,false);
}
else
searchtollbar.setVisibility(View.GONE);
return true;
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true;
}
});
initSearchView();
} else
Log.d("toolbar", "setSearchtollbar: NULL");
}
public void initSearchView()
{
final SearchView searchView = (SearchView) search_menu.findItem(R.id.action_filter_search).getActionView();
// Enable/Disable Submit button in the keyboard
searchView.setSubmitButtonEnabled(false);
// Change search close button image
ImageView closeButton = searchView.findViewById(R.id.search_close_btn);
closeButton.setImageResource(R.drawable.ic_close_black_24dp);
// closeButton.setImageResource(ContextCompat.getDrawable(getApplication(), R.drawable.ic_close_black_24dp));
// set hint and the text colors
EditText txtSearch = ((EditText) searchView.findViewById(R.id.search_src_text));
txtSearch.setHint("Search..");
txtSearch.setHintTextColor(Color.DKGRAY);
txtSearch.setTextColor(getResources().getColor(R.color.colorPrimary));
// set the cursor
AutoCompleteTextView searchTextView = (AutoCompleteTextView) searchView.findViewById(R.id.search_src_text);
try {
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.set(searchTextView, R.drawable.search_cursor); //This sets the cursor resource ID to 0 or #null which will make it visible on white background
} catch (Exception e) {
e.printStackTrace();
}
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
callSearch(query);
searchView.clearFocus();
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
callSearch(newText);
return true;
}
public void callSearch(String query) {
Log.i("query", "" + query);
}
});
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void circleReveal(int viewID, int posFromRight, boolean containsOverflow, final boolean isShow)
{
final View myView = findViewById(viewID);
int width=myView.getWidth();
if(posFromRight>0)
width-=(posFromRight*getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_material))-(getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_material)/ 2);
if(containsOverflow)
width-=getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_overflow_material);
int cx=width;
int cy=myView.getHeight()/2;
Animator anim;
if(isShow)
anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0,(float)width);
else
anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, (float)width, 0);
anim.setDuration((long)220);
// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
if(!isShow)
{
super.onAnimationEnd(animation);
myView.setVisibility(View.INVISIBLE);
}
}
});
// make the view visible and start the animation
if(isShow)
myView.setVisibility(View.VISIBLE);
// start the animation
anim.start();
}
public void setActionBarTitle(String title) {
mTitle.setText(title);
}
}
I think you are asking if we can create two tabs and when the user presses any of the tab, same fragment should appear instead of multiple fragments. If that is your question, may be i can help.
You will have to create one class that extends FragmentStateAdapter , then you should create a single class that extends Fragment instead of having multiple classes and a layout.
Create ClassFragmentPagerAdapter like this:
public class ClassFragmentPagerAdapter extends FragmentStateAdapter {
public ClassFragmentPagerAdapter (#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
#NonNull
#Override
public Fragment createFragment(int position) {
if (position == 0) {
return new ClassFragment ();
}
return new ClassFragment ();
}
#Override
public int getItemCount() {
return 2;
}
Then after that create the other ClassFragment that extends Fragment:
public class ClassFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup
container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.layout_name, container, false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
//do stuff here
}
Hope it helps! Happy coding:)
Good day. I need to change text color in of list view with the switch of a button click. List view with custom adapter and custom layout. Text view in newsitemlist_layout.xml inflated with adapter normal it works fine but in fragment give error "Adaptor.setTextColor(int)' on a null object reference." The problem is that adapter is initialized in fragment and switch or button in main activity if I implement change text color in fragment it works but not in main activity. So now need on click in main activity and change text color in the adapter. Is there any way to do this. Please help.
Main activity.java
NewsAdaptor adaptor;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)
findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick ( View view ) {
Snackbar.make(view, "Replace with your own action",
Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View headerView = navigationView.getHeaderView(0);
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#SuppressLint("ResourceAsColor")
#Override
public void onCheckedChanged ( CompoundButton buttonView,
boolean isChecked ) {
adaptor.setTextColor(Color.GREEN);
adaptor.notifyDataSetChanged();
} else {
adaptor.setTextColor(Color.RED);
adaptor.notifyDataSetChanged();
}
}
});
public boolean onNavigationItemSelected ( MenuItem item ) {
int id = item.getItemId();
if (id == R.id.nav_camera) {
FeagmentA expressMain = new FeagmentA ();
FragmentManager fragmentManager= getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.containerview,expressMain,expressMain.getTag())
.commit();
} else if (id == R.id.nav_gallery) {
Jungmain expressMain = new Jungmain();
FragmentManager fragmentManager= getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.containerview,expressMain,expressMain.getTag())
.commit();
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
Fragment.java
public class FragmentA extends Fragment {
public FragmentA() {
// Required empty public constructor
}
ListView lvRss;
ArrayList<NewsItem> newsItemsList;
NewsAdaptor adapter;
public static FragmentA newInstance(String param1, String param2) {
FragmentA fragment = new FragmentA();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_a, container, false);
lvRss = (ListView) view.findViewById(R.id.fragmentalistview);
newsItemsList = new ArrayList <>();
new n2().execute();
return view;
}
private class n2 extends AsyncTask<Integer,Void,Intent> {
#Override
protected Intent doInBackground ( Integer... integers ) {
try {
Document document = Jsoup.connect("http://feeds.bbci.co.uk/urdu/pakistan/rss.xml").ignoreHttpErrors(true).get();
Elements itemElements = document.getElementsByTag("item");
for (int i = 0; i < itemElements.size(); i++) {
Element item = itemElements.get(i);
NewsItem newsItem = new NewsItem();
newsItem.setImagePath(item.child(5).getElementsByTag("media:thumbnail").first().attr("url"));
newsItem.setDate(rem1(item.child(4).text()));
newsItem.setTitle(item.child(0).text());
newsItem.setLink(item.child(3).text());
newsItemsList.add(newsItem);
Collections.sort(newsItemsList, new Comparator<NewsItem>() {
#Override
public int compare ( NewsItem o1, NewsItem o2 ) {
return o1.dateInMilliSec > o2.dateInMilliSec ? -1 :
o1.dateInMilliSec < o2.dateInMilliSec ? 1 : 0;
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
getActivity(). runOnUiThread(new Runnable() {
#Override
public void run () {
adapter = new NewsAdaptor(getContext(), newsItemsList);
lvRss.setAdapter(adapter);
}
});
return null;
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
}
NewsAdapter.java
public class NewsAdaptor extends BaseAdapter {
TextView tvtitle;
Context context;
private int color;
public NewsAdaptor ( Context context, ArrayList <NewsItem> newsList ) {
this.context = context;
this.newsList = newsList;
this.color = Color.RED;
}
ArrayList <NewsItem> newsList;
#Override
public int getCount () {
return newsList.size();
}
#Override
public Object getItem ( int position ) {
return newsList.get(position);
}
#Override
public long getItemId ( int position ) {
return 0;
}
#SuppressLint("ResourceAsColor")
#Override
public View getView ( int position, View convertView, ViewGroup parent ) {
if (convertView == null) {
convertView = View.inflate(context, R.layout.newsitemlist_layout, null);
}
NewsItem currentNews = newsList.get(position);
tvtitle = (TextView) convertView.findViewById(R.id.textView1id);
tvtitle.setText(currentNews.getTitle());
tvtitle.setTextColor(color);
return convertView;
}
public void setTextColor(int color) {
this.color = color;
}
}
NewsItem.java
public class NewsItem implements Serializable {
String title;
public String getTitle () {
return title;
}
public void setTitle ( String title ) {
this.title = title;
}
#Override
public String toString() {
return title;
}
NewsItemlist.layout.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp">
<TextView
android:id="#+id/textView1id"
android:layout_width="237dp"
android:layout_height="83dp"
android:layout_alignEnd="#+id/pubDateid"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/pubDateid"
android:ellipsize="end"
android:gravity="right"
android:text="News TITLE"
android:textStyle="bold" />
Try this
Add this code in MainActivity Click event:
Fragment frag = getSupportFragmentManager().findFragmentById(R.id.containerview);
if(frag instanceof FragmentA )
{
((FragmentA ) frag).adapter.setTextColor(Color.RED);
((FragmentA ) frag).adapter.notifyDataSetChanged();
}
EDITED
Change this line
fragmentManager.beginTransaction().replace(R.id.containerview,expressMain,expressMain.getTag())
.commit();
To
fragmentManager.beginTransaction().replace(R.id.containerview,expressMain,"TAG_NAME").addToBackStack("TAG_NAME").commit();
Then find fragment from fragmentmanager in activity class like below:
Fragment frag = getSupportFragmentManager().findFragmentByTag("TAG_NAME");
Good day How can I call a fragment when the users will click the card inside MyAdapter class. I want to replace view from the adapter. I am using recyclerview wants to perform click event using the view from my row layout.
Like for example when the user clicks the card it will open a fragment and it will show more data. Hope you can help me guys.
This is my main fragment
AccountsFragment
ReceivableFragment
LoanAppFragment
Those fragments hold different data. when the user clicks the cards inside that fragment it will call another fragment the SLDTLFragment.
Btw this MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Datas> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
public CardView mCardView;
public TextView account_type;
public TextView accnt_description;
public TextView balance_label;
public TextView account_balance;
public MyViewHolder(View v) {
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
account_type = (TextView) v.findViewById(R.id.lblShareCapital);
balance_label = (TextView) v.findViewById(R.id.lblAvailableBalance);
accnt_description = (TextView) v.findViewById(R.id.sl_desc);
account_balance = (TextView) v.findViewById(R.id.actual_balance);
}
}
public MyAdapter(List<Datas> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_item, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
//holder.account_type.setText(mDataset[position]);
Datas datas = mDataset.get(position);
holder.accnt_description.setText(datas.getSL_DESC());
holder.account_balance.setText(datas.getACTUAL_BALANCE());
holder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// String sl_desc = mDataset.get(position).getSL_DESC();
// String actual_balance = mDataset.get(position).getACTUAL_BALANCE();
String sle = mDataset.get(position).getSLE();
String slc = mDataset.get(position).getSLC();
String slt = mDataset.get(position).getSLT();
String ref_no = mDataset.get(position).getREF();
Log.d("CardView Clicked", "sle code: " + sle);
Log.d("CardView Clicked", "slc code: " + slc);
Log.d("CardView Clicked", "slt code: " + slt);
Log.d("CardView Clicked", "ref no: " + ref_no);
}
});
}
#Override
public int getItemCount() {
return mDataset.size();
}
}
AccountsFragment.java
public class AccountsFragment extends Fragment {
private SQLiteHandler db;
public AccountsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_accounts, container, false);
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
rv.setHasFixedSize(true);
SQLiteHandler db = new SQLiteHandler(getActivity());
MyAdapter adapter = new MyAdapter(db.getUserSLDetails());
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
return rootView;
}
}
ReceivableFragment.java
public class ReceivableFragment extends Fragment {
public ReceivableFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_receivable, container, false);
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
rv.setHasFixedSize(true);
SQLiteHandler db = new SQLiteHandler(getActivity());
MyAdapter adapter = new MyAdapter(db.getUserSLARLoans());
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
return rootView;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView nav_header_name;
private TextView nav_header_email;
public TextView txtLogOut;
private SQLiteHandler db;
private SessionManager session;
private Timer timer;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Will replace the activity_main.xml to relativelayout_for_fragment.xml
if (savedInstanceState == null) {
AccountsFragment f1= new AccountsFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.relativelayout_for_fragment, f1);// relativelayout_for_fragment is inside the content_main.xml
fragmentTransaction.commit();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View header=navigationView.getHeaderView(0);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
txtLogOut = (TextView) findViewById(R.id.nav_logout_menu);
int id = item.getItemId();
if (id == R.id.nav_deposit) {
// Handle the preference action
AccountsFragment accounts= new AccountsFragment();
FragmentManager manager= getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.relativelayout_for_fragment, accounts)
.commit();
Toast.makeText(MainActivity.this, "Deposit Accounts", Toast.LENGTH_SHORT).show();
}else if (id == R.id.nav_receivable) {
// Handle the Loan application();
ReceivableFragment receivable= new ReceivableFragment();
FragmentManager manager= getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.relativelayout_for_fragment, receivable)
.commit();
Toast.makeText(MainActivity.this, "AR and Loan Accounts", Toast.LENGTH_SHORT).show();
}else if (id == R.id.nav_apply_loan_menu) {
// Handle the Loan application();
LoanAppFragment loan_app= new LoanAppFragment();
FragmentManager manager= getSupportFragmentManager();
manager.beginTransaction()
.replace(R.id.relativelayout_for_fragment, loan_app)
.commit();
Toast.makeText(MainActivity.this, "This module is under developement", Toast.LENGTH_SHORT).show();
}else if (id == R.id.nav_logout_menu) {
// Handle the About action
logoutUser();
//Toast.makeText(MainActivity.this, "successfully Logout", Toast.LENGTH_LONG).show();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
nav_header_name = (TextView) header.findViewById(R.id.nav_name);
nav_header_email = (TextView) header.findViewById(R.id.nav_email);
// SqLite database handler
db = new SQLiteHandler(getApplicationContext());
// session manager
session = new SessionManager(getApplicationContext());
if (!session.isLoggedIn()) {
logoutUser();
}
//Fetching user details from SQLite
HashMap<String, String> user = db.getUserDetails();
String username = user.get("username");
String email = user.get("email");
//Displaying the user info in nav_header_main.xml
nav_header_name.setText(username);
nav_header_email.setText(email);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Logging out the user. Will set isLoggedIn flag to false in shared
* preferences Clears the user data from sqlite users table
* */
private void logoutUser() {
session.setLogin(false);
db.deleteUsers();
db.deleteUserSLDTL();
// Launching the login activity
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
#Override
protected void onPause() {
super.onPause();
timer = new Timer();
Log.i("Main", "Invoking logout timer");
LogOutTimerTask logoutTimeTask = new LogOutTimerTask();
timer.schedule(logoutTimeTask, 30000); // auto logout in 30secs inactivity
Log.i("Main", "Log out user due to inactivity");
}
#Override
protected void onResume() {
super.onResume();
if (timer != null) {
timer.cancel();
Log.i("Main", "cancel timer");
timer = null;
}
}
private class LogOutTimerTask extends TimerTask {
#Override
public void run() {
session.setLogin(false);
db.deleteUsers();
db.deleteUserSLDTL();
//redirect user to login screen
Intent i = new Intent(MainActivity.this, LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
}
}
You need to use Listener/Callback pattern to inform your Activity or Fragment where the Adapter is used. Do not directly call a Fragment or activity inside of the Adapter because it will defeat the purpose of the Adapter. Adapter should only be used to show the data.
To implement the pattern, first create the interface and constructor to set the listener in your Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
...
private List<Datas> mDataset;
private ClickListener mListener;
public interface ClickListener {
void onItemClicked(YourData yourData);
}
public MyAdapter(List<Datas> myDataset, ClickListener listener) {
mDataset = myDataset;
mListener = listener;
}
...
}
Second, whenever there is a click of the item data, tell the listener with the following code in your Adapter:
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
...
holder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// String sl_desc = mDataset.get(position).getSL_DESC();
// String actual_balance = mDataset.get(position).getACTUAL_BALANCE();
// String sle = mDataset.get(position).getSLE();
// String slc = mDataset.get(position).getSLC();
// String slt = mDataset.get(position).getSLT();
// String ref_no = mDataset.get(position).getREF();
// Simplify the above to a pojo. We assume the pojo is YourData
YourData data = new YourData();
// set the data from above.
mListener.onItemClicked(yourData);
});
}
Third, you need to set the listener in your Activity/Fragment which using the Adapter with:
MyAdapter.ClickListener listener = new MyAdapter.ClickListener() {
#Override
public void onItemClicked(YourData yourData) {
// Do something with the data here.
}
};
MyAdapter adapter = new MyAdapter(db.getUserSLARLoans(), listener);
rv.setAdapter(adapter);
You need to handle the data in your listener inside the onItemClicked() method above.
try to pass getFragmentManager using constructor and then replace the view with container view in your item row.
//constructor
public MyAdapter(FragmentManager fragment, List<Datas> myDataset) {
mDataset = myDataset;
mFragment = fragment;
}
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public CardView mCardView;
public TextView account_type;
public TextView accnt_description;
public TextView balance_label;
public TextView account_balance;
public MyViewHolder(View v){
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
account_type = (TextView) v.findViewById(R.id.lblShareCapital);
balance_label = (TextView) v.findViewById(R.id.lblAvailableBalance);
accnt_description = (TextView) v.findViewById(R.id.sl_desc);
account_balance = (TextView) v.findViewById(R.id.actual_balance);
mCardView.setOnClickListener(this)
}
#Override
public void onClick(View view){
mFragment.beginTransaction().replace(R.id.containerRow,new MyFragment()).commit();
}
}
//note this is not tested code.
there is a MainActivity with it's fragment named FragmentOne. i have a List of items in this fragment and these data are save in my database
i make changes from NavigationView in MainActivity .. i try to delete all rows from my database. it works, but after that i need to refresh my FragmentOne, how can i refresh the FragmentOne UI ?
i have a method named updateUI in my FragmentOne but how could i access that method? when i make that method public everything just goes wrong!
i tested different ways but failed.. can anybody tell me how can i do this?
MainActivity :
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private TabLayout tabLayout;
private ViewPager viewPager;
private Detail mDetail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//////// TOOLBAR
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
actionBar.setDisplayHomeAsUpEnabled(true);
///////// DRAWER
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView =
(NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener
(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.nav_item_one:
return false;
case R.id.nav_item_two:
AlertDialog.Builder alert_delete = new AlertDialog.Builder(
MainActivity.this);
alert_delete.setTitle("Alert!");
alert_delete.setMessage(R.string.alert_delete_all);
alert_delete.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
DetailLab.get(getApplicationContext()).deleteAllDetail();
FragmentOne fragmentOne = new FragmentOne();
fragmentOne.getFragmentManager().beginTransaction().replace(R.id.card_view, fragmentOne)
.commit();
dialog.dismiss();
}
});
alert_delete.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert_delete.show();
return false;
..
..
case R.id.nav_item_nine:
finish();
default:
return false;
}
}
});
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOne(), "ONE");
adapter.addFragment(new FragmentTwo(), "TWO");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(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 null;
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
}
here is my method for delete all rows from database in another class called DetailLab :
public void deleteAllDetail() {
mDatabase.delete(DetailTable.NAME, null, null); }
and this is my FragmentOne:
public class FragmentOne extends Fragment {
private static final String SAVED_NUMBER_VISIBLE = "number";
private RecyclerView mDetailRecyclerView;
private DetailAdapter mAdapter;
private boolean mNumberVisible;
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_one_layout,
container, false);
mDetailRecyclerView = (RecyclerView)
view.findViewById(R.id.detail_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true); //This will reverse the data order but not scroll the RecyclerView to the last item
layoutManager.setStackFromEnd(true); //For keeping data order same and simply scrolling the RecyclerView to the last item
mDetailRecyclerView.setLayoutManager(layoutManager);
if (savedInstanceState != null) {
mNumberVisible =
savedInstanceState.getBoolean(SAVED_NUMBER_VISIBLE);
}
updateUI();
return view;
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_NUMBER_VISIBLE, mNumberVisible);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_one_layout, menu);
MenuItem numberItem = menu.findItem(R.id.show_numbers);
if (mNumberVisible) {
numberItem.setTitle(R.string.hide_numbers);
} else {
numberItem.setTitle(R.string.show_numbers);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.show_numbers:
mNumberVisible = !mNumberVisible;
getActivity().invalidateOptionsMenu();
updateNumbers();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void updateNumbers() {
DetailLab detailLab = DetailLab.get(getActivity());
int detailCount = detailLab.getDetails().size();
String number = getResources().getQuantityString
(R.plurals.number_plural, detailCount, detailCount);
if (!mNumberVisible) {
number = null;
}
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.getSupportActionBar().setSubtitle(number);
}
private void updateUI() {
DetailLab detailLab = DetailLab.get(getActivity());
List<Detail> details = detailLab.getDetails();
if (details.size() == 0) {
TextView t = (TextView) view.findViewById(R.id.empty);
t.setText(R.string.empty_view);
t.setVisibility(View.VISIBLE);
} else {
TextView t = (TextView) view.findViewById(R.id.empty);
t.setVisibility(View.GONE);
}
// Toast.makeText(getContext(), "zero", Toast.LENGTH_SHORT).show();
if (mAdapter == null) {
mAdapter = new DetailAdapter(details);
mDetailRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.setDetails(details);
mAdapter.notifyDataSetChanged();
}
updateNumbers();
}
private class DetailHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, View.OnLongClickListener {
private TextView mTitleTextView;
// private TextView mDateTextView;
private Detail mDetail;
private RatingBar mRatingBar;
public DetailHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.list_item_detail,
parent, false));
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
mTitleTextView = (TextView) itemView.findViewById(R.id.detail_title);
// mDateTextView = (TextView) itemView.findViewById(R.id.detail_date);
mRatingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
}
public void bind(Detail detail) {
mDetail = detail;
mTitleTextView.setText(mDetail.getTitle());
mRatingBar.setRating(mDetail.getRate());
}
#Override
public void onClick(View view) {
Intent intent = DetailPagerActivity.newIntent(getActivity(),
mDetail.getId());
startActivity(intent);
}
#Override
public boolean onLongClick(View v) {
AlertDialog.Builder alert = new AlertDialog.Builder(
getActivity());
alert.setMessage(R.string.alert);
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
DetailLab.get(getActivity()).deleteDetail(mDetail);
updateUI();
updateNumbers();
dialog.dismiss();
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
return true;
}
}
private class DetailAdapter extends RecyclerView.Adapter<DetailHolder> {
private List<Detail> mDetails;
public DetailAdapter(List<Detail> details) {
mDetails = details;
}
#Override
public DetailHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater =
LayoutInflater.from(getActivity());
return new DetailHolder(layoutInflater, parent);
}
#Override
public void onBindViewHolder(DetailHolder holder, int position) {
Detail detail = mDetails.get(position);
holder.bind(detail);
}
#Override
public int getItemCount() {
return mDetails.size();
}
public void setDetails(List<Detail> details) {
mDetails = details;
}
}
}
and here is my layout for FragmentOne :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_one_layout">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/detail_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="50dp"
android:textAlignment="center"
android:textSize="20sp"/>
</android.support.v7.widget.CardView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp"
android:src="#drawable/ic_menu_add"
android:scaleType="center"
app:elevation="8dp"
app:borderWidth="0dp"
/>
my logcat:
FATAL EXCEPTION: main
Process: com.drgnme.listhamrah, PID: 23454
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentTransaction android.support.v4.app.FragmentManager.beginTransaction()' on a null object reference
at com.drgnme.listhamrah.MainActivity$1$1.onClick(MainActivity.java:76)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I think you are having this issue because of the below code in your MainActivity:
FragmentOne fragmentOne = new FragmentOne();
fragmentOne.getFragmentManager().beginTransaction().replace(R.id.card_view, fragmentOne).commit();
You try to get the instance of the fragment manager with getFragmentManager() who call Activity.getFragmentManager but your fragmentOne isn't attach to the activity so the method return null and you get a java.lang.NullPointerException
Instead of fragmentOne.getFragmentManager() use getSupportFragmentManager() directly from the activity.
Hope this helps.
I have a method named updateUI in my FragmentOne but how could i
access that method?
To call the updateUI method of your FragmentOne
alert_delete.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
DetailLab.get(getApplicationContext()).deleteAllDetail();
Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
// based on the current position you can then cast the page to the correct
// class and call the method:
if (ViewPager.getCurrentItem() == 0 && page != null) {
((FragmentOne)page).updateUI();
}
dialog.dismiss();
}
});
To refresh a fragment's UI, use the fragment manager to detach and attach the same fragment again.
Eg:
public void refreshFragmentUI(Fragment fragment) {
getSupportFragmentManager()
.beginTransaction()
.detach(fragment)
.attach(fragment)
.commit();
}
Note: Use getSupportFragmentManager() if you are using support libraries. Else use getFragmentManager()
The best way to update data from SQLite Database in fragment is using LoaderManager.LoaderCallbacks and CursorAdapter. Because it is an Asynchronous process.
I have a MainActivity with two fragments. The second fragment has RecyclerView. There is TextView ( lesson name) and ImageView(show lesson status, if it is done or not) in RecyclerView . When you click TextView, it calls another Activity with lesson. After you make the lesson you will go back to MainActivity. After that lessons ImageView will be changed from nothing to resourse 'ic_lessondone'. Also there is a menu in MainActivity. Menu have item 'Reset lessons'. When you press 'Reset lessons' all ImageViews wont show any images. So there are two problems. 1) if I do, for example , only 6th lesson. I will have image 'lessondone'. When i press 'Reset lessons' image will disappear. But when i go back to menu again and press 'Reset lessons', Image will appear again and rise to previous lesson ( 5th). 2) If i switch off display, image will also appear to previous lessons till to 0th.
Its seems i have a problem with onResume.
Help me please.
public class MainActivity extends AppCompatActivity
{
private DrawerLayout mDrawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null)
{
setupDrawerContent(navigationView);
}
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
if (viewPager != null)
{
setupViewPager(viewPager);
}
// Круглая кнопка
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
Snackbar.make(view, "Here's a Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
// Картинки для табов
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.ic_home);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_lessons);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.sample_actions, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{
switch (AppCompatDelegate.getDefaultNightMode())
{
case AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM:
menu.findItem(R.id.menu_night_mode_system).setChecked(true);
break;
case AppCompatDelegate.MODE_NIGHT_AUTO:
menu.findItem(R.id.menu_night_mode_auto).setChecked(true);
break;
case AppCompatDelegate.MODE_NIGHT_YES:
menu.findItem(R.id.menu_night_mode_night).setChecked(true);
break;
case AppCompatDelegate.MODE_NIGHT_NO:
menu.findItem(R.id.menu_night_mode_day).setChecked(true);
break;
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
case R.id.menu_night_mode_system:
setNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
break;
case R.id.menu_night_mode_day:
setNightMode(AppCompatDelegate.MODE_NIGHT_NO);
break;
case R.id.menu_night_mode_night:
setNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break;
case R.id.menu_night_mode_auto:
setNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
break;
}
return super.onOptionsItemSelected(item);
}
private void setNightMode(#AppCompatDelegate.NightMode int nightMode)
{
AppCompatDelegate.setDefaultNightMode(nightMode);
if (Build.VERSION.SDK_INT >= 11)
{
recreate();
}
}
private void setupViewPager(ViewPager viewPager)
{
Adapter adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new Fragment(), "");
adapter.addFragment(new LessonsListFragment(), "");
viewPager.setAdapter(adapter);
}
// Главное меню
private void setupDrawerContent(NavigationView navigationView)
{
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
menuItem.setChecked(true);
if (menuItem.getTitle().equals("Reset lessons"))
{
// Обнуляем файл с рузультатами уроков
LessonsListFragment.sLessonsPref.edit().clear().commit();
// Перерисовываем весь писок уроков
LessonsListFragment.rv.getAdapter().notifyItemRangeChanged(0, LessonsListFragment.rv.getAdapter().getItemCount());
}
mDrawerLayout.closeDrawers();
return true;
}
});
}
static class Adapter extends FragmentPagerAdapter
{
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public Adapter(FragmentManager fm)
{
super(fm);
}
public void addFragment(Fragment fragment, String title)
{
mFragments.add(fragment);
mFragmentTitles.add(title);
}
// Получаем конкретный фрагмент
#Override
public Fragment getItem(int position)
{
return mFragments.get(position);
}
// Количество фрагментов для viewpager (2)
#Override
public int getCount()
{
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position)
{
return mFragmentTitles.get(position);
}
}
}
Fragment
public class LessonsListFragment extends Fragment
{
// Уроки
// static private Map<String,?> mLessonsKeys ;
static SharedPreferences sLessonsPref;
static RecyclerView rv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
loadSharedPreferenses();
rv = (RecyclerView) inflater.inflate(R.layout.fragment_cheese_list, container, false);
setupRecyclerView(rv);
return rv;
}
// Загружаем список пройденных уроков
public void loadSharedPreferenses()
{
sLessonsPref = this.getActivity().getSharedPreferences("LessonsResults", Context.MODE_PRIVATE);
}
// Количество строк в листе
private void setupRecyclerView(RecyclerView recyclerView)
{
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(getActivity(), getRandomSublist(Cheeses.sCheeseStrings, Cheeses.sCheeseStrings.length)));
}
// Задаем Строки
private List<String> getRandomSublist(String[] array, int amount)
{
ArrayList<String> list = new ArrayList<>(amount);
//Random random = new Random();
while (list.size() < amount)
{
list.add(array[list.size()]);
}
return list;
}
//Отработка перерисования окна, при возврате к ней
#Override
public void onResume()
{
super.onResume();
//loadSharedPreferenses();
//Toast.makeText(null, "Refreshed", Toast.LENGTH_SHORT).show();
if (rv.getAdapter() != null)
{
rv.getAdapter().notifyDataSetChanged();
}
}
// Адаптер
public static class SimpleStringRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder>
{
private final TypedValue mTypedValue = new TypedValue();
private int mBackground;
private List<String> mValues;
public static class ViewHolder extends RecyclerView.ViewHolder
{
// Номер урока, передается в webactivity
public int mLessonNumber;
public final View mView;
public final ImageView mImageView;
public final TextView mTextView;
public ViewHolder(View view)
{
super(view);
mView = view;
mImageView = (ImageView) view.findViewById(R.id.avatar);
mTextView = (TextView) view.findViewById(android.R.id.text1);
}
#Override
public String toString()
{
return super.toString() + " '" + mTextView.getText();
}
}
public String getValueAt(int position)
{
return mValues.get(position);
}
public SimpleStringRecyclerViewAdapter(Context context, List<String> items)
{
context.getTheme().resolveAttribute(R.attr.selectableItemBackground, mTypedValue, true);
mBackground = mTypedValue.resourceId;
mValues = items;
}
// Создаем холдер с полезной нагрузкой
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
view.setBackgroundResource(mBackground);
return new ViewHolder(view);
}
//Создаем список уроков
#Override
public void onBindViewHolder(final ViewHolder holder, int position)
{
holder.mLessonNumber = position + 1;
// Увеличиваем позицион на 1 что не было 0 урока
holder.mTextView.setText((position + 1) + " " + mValues.get(position));
// Если урок пройден
String finished = sLessonsPref.getString((position + 1) + "", "");
if (finished.equals("1"))
{
// Меняем его цвет
//holder.mTextView.setTextColor(R.color.white);
Glide.with(holder.mImageView.getContext()).load(R.drawable.ic_lessondone)
//.load(Cheeses.getRandomCheeseDrawable())
.fitCenter()
.into(holder.mImageView);
Log.d("Glide", "Work");
}
else
{
holder.mTextView.setTextColor(R.color.black);
// holder.mImageView.setVisibility(View.GONE);
}
// Вызов WebActivity
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
Context context = v.getContext();
Intent intent = new Intent(context, WebActivity.class);
// Передаем вебвью номер урока и запускаем ее
intent.putExtra(WebActivity.EXTRA_NAME, holder.mLessonNumber);
context.startActivity(intent);
}
});
}
// Определяем количество выводимых строк
#Override
public int getItemCount()
{
return mValues.size();
}
}
}
Implement a reset() method in the adapter that mark all items as "not done" and then try:
LessonsListFragment.rv.getAdapter().reset();
LessonsListFragment.rv.getAdapter().notifyDataSetChanged();
instead of:
LessonsListFragment.rv.getAdapter().notifyItemRangeChanged(0, LessonsListFragment.rv.getAdapter().getItemCount());
inside onNavigationItemSelected.
Also, you shouldn't be using static variables (like static RecyclerView rv), use private vars with getters
The problem was in else statement. I added there this code, and now its ok. notifydatachanged work correctly from navigationview
if (finished.equals("1"))
{
// Меняем его цвет
//holder.mTextView.setTextColor(R.color.white);
Glide.with(holder.mImageView.getContext()).load(R.drawable.ic_lessondone)
.fitCenter()
.into(holder.mImageView);
Log.d("Glide", "Work");
}
else
{
Glide.with(holder.mImageView.getContext()).load(R.color.white)
.fitCenter()
.into(holder.mImageView);
holder.mTextView.setTextColor(R.color.black);
}