How to access to Activity views from Fragment through DataBinding? - android-fragments

My aim is to access MainActivity's ProgressBar and TextView from a Fragment. However, I am getting the error below:
Attempt to invoke virtual method 'void
android.widget.ProgressBar.setVisibility(int)' on a null object
reference
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:orientation="vertical"
android:layout_gravity="center">
<ProgressBar
android:id="#+id/pbLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="center"
android:visibility="visible"/>
<TextView
android:id="#+id/tvLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="#dimen/dimension_8dp"
android:fontFamily="#font/robotomedium"
android:textSize="16sp"
android:visibility="visible"
android:text="#string/loading_text"/>
</LinearLayout>
SampleFragment.java
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragmentDataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_currency_list, container, false);
return Objects.requireNonNull(fragmentDataBinding).getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
mPbLoading = fragmentDataBinding.getRoot().findViewById(R.id.pbLoading);
mPbLoading.setVisibility(View.GONE);
}
Tampered with lots of posts, articles but couldn't achieve it. Thanks in advance.
Best,

Option 1
make progressbar static on activity
and then access from fragment like -
if(MainActivity.progressbar!=null){
MainActivity.progressbar.setVisibility(View.Gone);
//or whatever do you want
}
Option 2
((YourActivityClassName)getActivity()).yourPublicMethod();

Related

Is there a way to make recyclerview expandable by using FirestoreRecyclerAdapter?

Is it possible to expand each holder like in onBindViewHolder? How to get the position and use isExpanded?
EDIT
Screenshot
So this is what I've done so far in my recyclerView using FirestoreRecyclerAdapter. I haven't figure out how to construct my xml and to expand it on my Adapter. I want to hide the seekbar first and show it when it gets expanded.
This is my Adapter
public class TaskAdapter extends FirestoreRecyclerAdapter <Activities, TaskAdapter.TaskHolder> {
private static final String TAG = "TaskAdapter";
TaskListener listener;
public TaskAdapter(#NonNull FirestoreRecyclerOptions<Activities> options, TaskListener listener) {
super(options);
this.listener = listener;
}
#Override
protected void onBindViewHolder(#NonNull TaskHolder holder, int position, #NonNull Activities activities) {
holder.tvTitle.setText(activities.getTitle());
}
#NonNull
#Override
public TaskHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.layout_list_tasks, parent, false);
return new TaskAdapter.TaskHolder(view);
}
class TaskHolder extends RecyclerView.ViewHolder{
TextView tvTitle, tvPercent;
ConstraintLayout expandableLayout;
public TaskHolder(#NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvActivityTitle);
expandableLayout = itemView.findViewById(R.id.expandableLayout);
}
}
public interface TaskListener{
void onItemClick(DocumentSnapshot documentSnapshot, int position);
}
}
This is my XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvActivityTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:maxLines="1"
android:padding="16dp"
android:text="Title"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/expandableLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvActivityTitle">
<TextView
android:id="#+id/percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="%"
android:textAppearance="#style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
app:layout_constraintStart_toEndOf="#+id/percent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>

Blank screen when trying to implement MVVM / ViewModel and data binding architecture

I am trying to implement the Model-View-ViewModel architectural pattern and XML data binding in my Android Java app. The code seems all correct as far as I can see, however I'm getting a blank screen when I run the app (not even the bottomNavigationView is showing). I am using a ViewModel to store/persist data for a fragment called AllTimeBestFragment. Specifically, AllTimeBestFragment is one of three fragments in a Viewpager-tabLayout.
Would appreciated any insight into what I'm doing wrong!
AllTimeBestFragment
public class AllTimeBestFragment extends Fragment {
private ImageViewCallback imageViewCallback;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(Constants.SkiCompanionDebug, "AllTimeBestFragment");
bindToViewModel();
return inflater.inflate(R.layout.fragment_all_time_best, container, false);
}
//imageview callback
#Override
public void setUserVisibleHint(boolean visible) {
super.setUserVisibleHint(visible);
imageViewCallback.setImage(R.drawable.all_time_best);
}
public void addCallback(ImageViewCallback imageViewCallback) {
this.imageViewCallback = imageViewCallback;
}
//binding the view (fragment) to the asoociated viewModel
public void bindToViewModel(){
FragmentAllTimeBestBinding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_all_time_best);
AllTimeBestViewModel viewModel = ViewModelProviders.of(this).get(AllTimeBestViewModel.class);
AllTimeStats allTimeStats = BCCDatabase.getInstance(getActivity()).getAllTimeStats();
viewModel.init(allTimeStats);
binding.setAllTimeBestViewModel(viewModel);
}
}
AllTimeBestViewModel
public class AllTimeBestViewModel extends ViewModel {
private AllTimeStats allTimeStats;
public void init(AllTimeStats allTimeStats) {
this.allTimeStats = allTimeStats;
}
public String getDurationTotal(){
return ""+allTimeStats.getDurationTotal();
}
}
fragment_all_time_best.xml
<data>
<variable
name="allTimeBestViewModel"
type="skicompanion.skicompanion.viewmodels.AllTimeBestViewModel" />
</data>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/track_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context="skicompanion.skicompanion.fragments.AllTimeBestFragment">
<android.support.v7.widget.CardView
android:id="#+id/duration_cardview"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/duration_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{allTimeBestViewModel.durationTotal}"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="#+id/duration_total_tv"
app:layout_constraintStart_toStartOf="#+id/imageView2"
app:layout_constraintTop_toBottomOf="#+id/duration_total_tv" />
...
...
...
Gradle
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
I found the answer here: How to use data-binding with Fragment
I was binding the data as if I were dealing with an activity - I needed to bind it for a fragment instead. The trick was to use DataBindingUtil.inflate rather than DataBindingUtil.setContentView. Below is the correct code snippet:
public class AllTimeBestFragment extends Fragment {
private ImageViewCallback imageViewCallback;
private FragmentAllTimeBestBinding binding;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(Constants.SkiCompanionDebug, "AllTimeBestFragment");
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_all_time_best, container, false);
bindToViewModel();
return binding.getRoot();
}
//imageview callback
#Override
public void setUserVisibleHint(boolean visible) {
super.setUserVisibleHint(visible);
imageViewCallback.setImage(R.drawable.all_time_best);
}
public void addCallback(ImageViewCallback imageViewCallback) {
this.imageViewCallback = imageViewCallback;
}
//binding the view (fragment) to the asoociated viewModel
public void bindToViewModel(){
AllTimeBestViewModel viewModel = ViewModelProviders.of(this).get(AllTimeBestViewModel.class);
AllTimeStats allTimeStats = BCCDatabase.getInstance(getActivity()).getAllTimeStats();
viewModel.init(allTimeStats);
binding.setAllTimeBestViewModel(viewModel);
}
}

In Android, how to replace a Fragment in a Tablayout?

For the love of god, I can't seem to figure this out. I have a tablayout with 3 tabs (each tab has in it a fragment). All i want to do is on the second fragment, the user clicks a button, and it replaces the second tab's fragment with a new fragment. So how do I go about doing that?
Here is my xml for the fragment I want to replace .
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragCards_mainLL">
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp"
android:id="#+id/fragCards_LL">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/fragCards_RecyclerView">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</FrameLayout>
And here is the fragment I want to replace the second tab's fragment.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.daprlabs.swipedeck.ProfileView.FragmentFollowers"
android:id="#+id/fragFollowrs_mainFL">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Followers Fragment"
android:gravity="center"
android:textSize="30dp"/>
</FrameLayout>
Here is my viewpageAdapter code
public class ViewPagerAdapter extends FragmentPagerAdapter
{
ArrayList<Fragment> fragments = new ArrayList<>();
ArrayList<String> tabTitles = new ArrayList<>();
public ViewPagerAdapter(android.support.v4.app.FragmentManager fragmentManager)
{
super(fragmentManager);
}
#Override
public Fragment getItem(int position)
{
return fragments.get(position);
}
#Override
public int getCount()
{
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position)
{
return tabTitles.get(position);
}
public void addFragments(Fragment fragment, String titles)
{
this.fragments.add(fragment);
this.tabTitles.add(titles);
}
}
Now somewhere in my Tab 2 fragment I have an onClickListener, I need to replace the entire fragment with a new fragment. I am not sure what to put in here...Currently, my "Followers Fragment" just goes beneath my recyclerview, so I can still see the views in the current, so it doesn't entirely replace the fragment...
#Override
public void onClick(View v)
{
FragmentFollowers f1 = new FragmentFollowers();
android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragCards_LL,f1);
fragmentTransaction.setTransition(android.support.v4.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Toast.makeText(getActivity(),"position " +position,Toast.LENGTH_SHORT).show();
}

Call a function in surfaceview class from a fragment in android

I have a surfaceview class in which there is a method updateValue(). This surface view is inside a fragment(framelayout). I am trying to call the method updateValue() from the fragment class. But it is not working.
public class ImageSurface extends SurfaceView implements SurfaceHolder.Callback {
......
public void updateValue(int message){
.......
}
}
xml file in which this surfaceview is declared.
fragment_main.xml --->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.paint.drawx.MainActivity$PlaceholderFragment" >
<com.paint.drawx.ImageSurface
android:id ="#+id/imagesurface1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</FrameLayout>
<fragment android:name="com.paint.drawx.DrawTools"
android:id="#+id/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#FF889911"
/>
</android.support.v4.widget.DrawerLayout>
fragment class ----
public static class PlaceholderFragment extends Fragment {
ImageSurface imageSurface;
public PlaceholderFragment() {
//imageSurface = (ImageSurface)findViewById(R.id.imagesurface1);
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
imageSurface = (ImageSurface)activity.findViewById(R.id.imagesurface1);
}
public void setMessage(int mess){
try{
imageSurface.updateValue(mess);////////this is not working. gives error nullpoint exception
}catch(Exception e){
Log.d("error","is"+e.toString());
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
setRetainInstance(true);
return rootView;
}
}
in the above class there is a method setMessage from which i call the method updateValue of the ImageSurface class but it gives null point exception. what am i doing wrong .
Thanks in advance.
I removed this line from onAttach() method
imageSurface = (ImageSurface)activity.findViewById(R.id.imagesurface1);
and inserted this line in onCreateView()
imageSurface = (ImageSurface) rootView.findViewById(R.id.imagesurface1);
and every thing is fine

Android:Fragment No View for ID for fragment

I am trying to implement action bar tabs and during which i am facing an error in implementing the fragment class.
public class fragmentImplement extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.fragment_layout);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_layout, container, false);
}
}
And XML file is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:id="#+id/textView1"
android:text="Fragment A"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
kindly help as i am getting very depressed
Please provide some more information (which error and where etc.) next time.
To use a Fragments you also need a FragmentActivity. A Fragment is a reusable component which you can use in a FragmentActivity.
Please use this tutorial as a starting point for using Fragments then go one step further and take a look into this article.
As far as I remember there is also an example in the Android SDK which has an ActionBar with tabs.

Resources