Base Activity abstract class methods not executing in other activities - java

i have created a base activity with a progressbar and a framelayout to inflate other activity layouts which are extending base activity. but when i call the showProgressbar method from base activity in other activities. nothing happens. it doesn't showup.
activity_base.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/activity_content"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/Widget.AppCompat.ProgressBar"
android:id="#+id/progress_bar"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
BaseActivity.class
public abstract class BaseActivity extends AppCompatActivity {
private ProgressBar mProgressbar;
#Override
public void setContentView(int layoutResID) {
ConstraintLayout constraintLayout = (ConstraintLayout) getLayoutInflater().inflate(R.layout.activity_base,null);
FrameLayout frameLayout = constraintLayout.findViewById(R.id.activity_content);
mProgressbar = constraintLayout.findViewById(R.id.progress_bar);
getLayoutInflater().inflate(layoutResID,frameLayout,true);
super.setContentView(layoutResID);
}
public void showProgressBar(boolean visibility){
mProgressbar.setVisibility(visibility ? View.VISIBLE : View.INVISIBLE);
}
}
MainActivity.class
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
showProgressBar(true);
}
}

replace this : super.setContentView(layoutResID)
with this : super.setContentView(constraintLayout); you are trying to have base layout and child activity layout and you are inflating them correctly but when you pass super.setContentView your child layoutResID all above code is ignored.

Related

Android/Java: How to access to my BottomNavigationView specific variables from another activity?

I would like to access to a variable initialization from NewBottomNav in LocalNav, but I don't know how to access it?
NewBottomNav class:
public final class newBottomNav extends BottomNavigationView {
private final Context context;
private Typeface fontFace = null;
public static Integer initialization = 0;
...
}
LocalNav Class:
public class LocalNav extends AppCompatActivity {
Context mContext;
WebView view;
BottomNavigationView bottomNavigation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int size = bottomNavigation.getMenu().size();
bottomNavigation.setOnNavigationItemSelectedListener (new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem Item) {
bottomNavigation.initialization = 1; //<= How to access to initialization
...
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/relativeLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LocalNav">
<WebView
android:id="#+id/vieweb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="0dp"
android:layout_marginBottom="-2dp"
app:layout_constraintBottom_toTopOf="#+id/bottom_nav"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.NewTelApps.ToEvent.newBottomNav
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
app:itemIconSize="45dp"
android:visible="false"
app:itemBackground="#drawable/nav_item_drawable"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_nav_menu"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
I don't know how to access it because it is a BottomNavigationView. Is there any specific things to do?
Thanks in advance.
You just need to change the declaration from
BottomNavigationView bottomNavigation;
to
newBottomNav bottomNavigation;
As initialization is not defined in BottomNavigationView

Cannot view progressBar created in BaseActivity(parent) in MainActivity(child)?

I am trying to make a single base activity for all the redundant actions. I tried putting the progress bar in BaseActivity and tried extending it in MainActivity, But it is not showing up at all.
My Code
activity_base.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<FrameLayout
android:id="#+id/activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<ProgressBar
android:id="#+id/progressBar"
android:indeterminate="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
BaseActivity.java
public abstract class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
public ProgressBar progressBar;
#Override
public void setContentView(int layoutResID) {
ConstraintLayout constraintLayout = (ConstraintLayout) getLayoutInflater().inflate(R.layout.activity_base, null);
FrameLayout frameLayout = constraintLayout.findViewById(R.id.activity_content);
progressBar = constraintLayout.findViewById(R.id.progressBar);
Log.i(TAG, "setContentView: Progressbar" + progressBar.getVisibility());
getLayoutInflater().inflate(layoutResID, frameLayout, true);
super.setContentView(layoutResID);
}
public void showProgressBar(boolean visibility) {
progressBar.setVisibility(visibility ? View.VISIBLE : View.GONE);
}
}
MainActivity.java
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_get_data = (Button) findViewById(R.id.btn_get_data);
btn_get_data.setOnClickListener(view -> {
if (progressBar.getVisibility() == View.VISIBLE) {
Log.i(TAG, "onCreate: DISABLING PROGRESS BAR");
showProgressBar(false);
} else {
showProgressBar(true);
}
}
}
There are other things in the app, but they have no connection with the progress bar. And yes I have declared the button and other things properly.
Thanks in advance!
Change
super.setContentView(layoutResID);
to
super.setContentView(constraintLayout);
in setContentView() method of the BaseActivity.

First fragment remains in the background after transition

I am currently trying to create an app having a splash screen, a login screen and a register screen.
The only way to achieve exactly what I need is through fragments. Though when I try to transition from the splash screen to the login fragment the text view which was part of the splash screen remains. The same happens after transitioning from the login fragment to the register fragment as well as from the register fragment back to the login fragment. It is important to note that there is no issue during transitioning between login and register or between register and login - except the fact that the edit text stays there.
My MainActivity.java
public class StartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
}
#Override
public void onBackPressed(){
Toast.makeText(getApplicationContext(), "Back button is disabled", Toast.LENGTH_SHORT).show();
}
}
My layout for MainActivity
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
tools:context=".StartActivity"
android:background="#mipmap/background">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewpagerstart"
android:layout_centerInParent="true"
android:name="com.example.distributedsystemsui.SplashFragment">
</fragment>
</RelativeLayout>
The SplashScreen.java
public class SplashFragment extends Fragment {
LinearLayout linearLayout;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_splash, container, false);
linearLayout = (LinearLayout) view.findViewById(R.id.f_linearsplash);
Animation animation_fadein = AnimationUtils.loadAnimation((StartActivity)getActivity(), R.anim.fade_in);
linearLayout.startAnimation(animation_fadein);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_enter_left, R.anim.slide_exit_left,
R.anim.slide_enter_right, R.anim.slide_exit_right);
LoginFragment loginFragment = LoginFragment.newInstance();
ft.replace(R.id.viewpagerstart, loginFragment);
ft.commit();
}
}, 3000);
return view;
}
}
And the layout for the SplashScreen fragment.
<?xml version="1.0" encoding="utf-8"?>
<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=".LoginFragment"
android:background="#color/Tranparent"
android:id="#+id/frame_splash">
<LinearLayout
android:id="#+id/f_linearsplash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/f_splashlogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="70dp"
android:background="#FFFFFF"/>
<TextView
android:id="#+id/f_splashtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:layout_gravity="center_horizontal"
android:layout_marginTop="100dp"
android:background="#FFFFFF"/>
</LinearLayout>
</FrameLayout>
All my search led back to nothing.
I can only assume that either the below contained in the MainActivity.xml creates a confusion (which I tried to change but no luck):
android:name="com.example.distributedsystemsui.SplashFragment"
or that I am doing a mistake in the SplashScreen.java that I cannot locate, even though I tried for more than 5 hours to make it work.
The problem is that you cannot replace fragments added via the <fragment> tag.
Instead, you should either:
1) Switch to FragmentContainerView, which was added in Fragment 1.2.0. It does not suffer from the same issue as the <fragment> tag and lets you do replace operations without issues:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
tools:context=".StartActivity"
android:background="#mipmap/background">
<androidx.fragment.app.FragmentContainerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewpagerstart"
android:layout_centerInParent="true"
android:name="com.example.distributedsystemsui.SplashFragment">
</androidx.fragment.app.FragmentContainerView>
</RelativeLayout>
2) Use a FrameLayout in your layout and manually add the SplashFragment in your activity (this is essentially what FragmentContainerView does for you):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
tools:context=".StartActivity"
android:background="#mipmap/background">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewpagerstart"
android:layout_centerInParent="true">
</FrameLayout>
</RelativeLayout>
which means you need to add the SplashFragment manually:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.viewpagerstart, new SplashFragment())
.commit()
}
}
I think it is better to do the fragment transactions from your activity instead of doing it from your fragment. You might consider having functions in your MainActivity as follows.
public class StartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
}
public void goToLoginFragment() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_enter_left, R.anim.slide_exit_left,
R.anim.slide_enter_right, R.anim.slide_exit_right);
LoginFragment loginFragment = LoginFragment.newInstance();
ft.replace(R.id.viewpagerstart, loginFragment);
ft.commit();
}
public void goToRegisterFragment() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_enter_left, R.anim.slide_exit_left,
R.anim.slide_enter_right, R.anim.slide_exit_right);
LoginFragment registerFragment = RegisterFragment.newInstance();
ft.replace(R.id.viewpagerstart, registerFragment);
ft.commit();
}
#Override
public void onBackPressed(){
Toast.makeText(getApplicationContext(), "Back button is disabled", Toast.LENGTH_SHORT).show();
}
}
And then from your SplashFragment call the function that is defined in your activity.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
((MainActivity) getActivity()).goToLoginFragment();
}
}, 3000);
I hope that solves the problem.

tabbed layout inside fragment not working properly

i'm a beginner trying to apply the idea of having tabbed layout inside a "main" fragment that allows me to navigate to other "secondary fragments" as well, there is a main activity with a button which when clicked will inflate the tabbed fragment inside this activity.
but what i got is this: the tabs are duplicated on just the first fragment for some reason.
here is my code: MainActiviy.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void fragny(View view) {
FragmentTransaction ft=getSupportFragmentManager().beginTransaction();
ft.replace(R.id.ma,new labRatFrag());
ft.commit();
}
}
main_activity.xml
<androidx.constraintlayout.widget.ConstraintLayout 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/ma"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:onClick="fragny"
/>
FragmentPagerAdapter
public class FragAdapt extends FragmentPagerAdapter {
private static final String[] TAB_TITLES = new String[]{"test1","test2","test3"};
private final Context mContext;
public FragAdapt(Context context ,FragmentManager fm) {
super(fm);
mContext=context;
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new labRatFrag();
case 1:
return new labRatFrag2();
case 2:
return new labRatFrag3();
default:
return null;
}
}
#Override
public String getPageTitle(int position) {
return TAB_TITLES[position];
}
#Override
public int getCount() {
return 3;
}
}
my main fragment (labRatFrag.java)
public class labRatFrag extends Fragment {
public labRatFrag() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.fragment_lab_rat, container, false);
FragAdapt fa=new FragAdapt(getContext(),getActivity().getSupportFragmentManager());
ViewPager vp=v.findViewById(R.id.pagery);
vp.setAdapter(fa);
TabLayout tabs = v.findViewById(R.id.toto);
tabs.setupWithViewPager(vp);
return v;
}
}
fragment_lab_rat.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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="match_parent"
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
>
<com.google.android.material.tabs.TabLayout
android:id="#+id/toto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/pagery"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
i want to do this in order to apply this idea with bottom navigation or navigation drawer for a future app i'm planning
FragAdapt is for your secondary fragment, right?
if yes, try replacing
FragAdapt fa=new FragAdapt(getContext(),getActivity().getSupportFragmentManager());
with
FragAdapt fa=new FragAdapt(getContext(),getChildFragmentManager());.
It might help. If not, will prepare a demo for you

Fragment Not Displaying In Activity

Currently when running my application, going to this activity does not display my fragment. Am I adding the fragment wrong and so nothing in the fragment is displayed? Or is there something wrong the dynamic behavior in the fragment onCreateView method?
My Activity Code
public class AskQuestionActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ask_question);
}
}
My Activity XML
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="#string/header_text"/>
<fragment android:name="com.mypackage.AskQuestionFragment"
android:id="#+id/question_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
My Fragment Code
public class AskQuestionFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String questionText = "What is your favorite color?";
List<String> answers = Arrays.asList("Red", "Blue", "Yellow");
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, container);
Resources res = getResources();
int id = res.getIdentifier("question_text", "id", layout.getContext().getPackageName());
TextView questionTextView = (TextView)layout.findViewById(id);
questionTextView.setText(questionText);
id = res.getIdentifier("question_answers", "id", layout.getContext().getPackageName());
RadioGroup radioGroup = (RadioGroup)layout.findViewById(id);
Collections.reverse(answers);
for (String s : answers) {
RadioButton button = new RadioButton(layout.getContext());
button.setText(s);
radioGroup.addView(button, 0);
}
return layout;
}
}
My Fragment XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/question_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/question_text"/>
<RadioGroup android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/question_answers"></RadioGroup>
<Button
android:id="#+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/submit_button_text"
/>
</LinearLayout>
try to put framelayout instead of fragment in xml. and in your activity's onCreate create the instance of your fragment you want to display and add it to the fragment container
public class AskQuestionActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ask_question);
AskQuestionFragment fragment = new AskQuestionFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.id_of_your_container, fragment).commit();
}
}
Your problem might be when doing this:
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, container);
Consider to replace that line with one of the following:
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, null);
or
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, container, false);
change your layout from linear to be framelayout, and attach your fragment in activity .
getSupportFragmentManager().beginTransaction()
.add(R.id.your_fragment_container, fragment).commit();

Categories