I have the following simple code for testing fragments transactions as I'm relatively new to Android : At first , I just show the first fragment and everything goes fine , but when I want it to be changed after a button is clicked , I get the following error :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.onceuponatime, PID: 3161
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1864)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:649)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)
at com.example.user.onceuponatime.activity.AuthentificationActivity.onFragmentSwapRequested(AuthentificationActivity.java:63)
at com.example.user.onceuponatime.fragment.SignInFragment$2.onClick(SignInFragment.java:95)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Activity :
public class AuthentificationActivity extends AppCompatActivity implements SignInFragment.SignInFragmentCallBack
,SignUpFragment.SignUpFragmentCallBack{
public static final String SIGNINFRAGMENT_TAG = "signinfragment";
public static final String SIGNUPFRAGMENT_TAG = "signupfragment";
public static final int SIGNIN_FRAGMENT_ID = 846464;
public static final int SIGNUP_FRAGMENT_ID = 125478;
public static final int LOST_PWD_FRAGMENT_ID = 85546;
private FragmentManager mFragmentManager;
private SignInFragment mSignInFragment;
private SignUpFragment mSignUpFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authentification);
mSignInFragment = SignInFragment.getInstance();
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.add(mSignInFragment,SIGNINFRAGMENT_TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
#Override
public void onFragmentSwapRequested(int FragmentId) {
mFragmentManager = this.getSupportFragmentManager();
FragmentTransaction fgTransaction = mFragmentManager.beginTransaction();
switch(FragmentId) {
case SIGNUP_FRAGMENT_ID:
if(!isFinishing()) {
mSignUpFragment = (SignUpFragment) mFragmentManager.findFragmentByTag(SIGNUPFRAGMENT_TAG);
if (mSignUpFragment == null) {
mSignUpFragment = SignUpFragment.getInstance();
fgTransaction.replace(R.id.fragment_container, mSignUpFragment, SIGNUPFRAGMENT_TAG);
} else {
fgTransaction.show(mSignUpFragment);
}
fgTransaction.addToBackStack(null);
fgTransaction.commit();
}
break;
case LOST_PWD_FRAGMENT_ID:
break;
}
}
}
SignUpFragment :
public class SignUpFragment extends Fragment {
FragmentSignUpBinding signUpBinding;
private EditText mEmailEdit,mPasswordEdit;
private Button btnRegister,btnLogin;
private ProgressBar mProgressBar;
private CoordinatorLayout mCoordinatorLayout;
private FirebaseAuth mAuth;
private SignUpFragmentCallBack mCallBack;
public interface SignUpFragmentCallBack {
void onFragmentSwapRequested(int fragmentId);
}
public SignUpFragment() {
}
public static SignUpFragment getInstance() {
SignUpFragment fragment = new SignUpFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
signUpBinding = DataBindingUtil.setContentView(getActivity(),R.layout.fragment_sign_up);
mEmailEdit = signUpBinding.emailSignup;
mPasswordEdit = signUpBinding.passwordSignup;
btnLogin = signUpBinding.loginRedirectButton;
btnRegister = signUpBinding.registerButton;
mProgressBar = signUpBinding.progressBarSignup;
mCoordinatorLayout = signUpBinding.coordinatorSignup;
mCallBack = new AuthentificationActivity();
mAuth = FirebaseAuth.getInstance();
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mCallBack instanceof SignUpFragmentCallBack)
mCallBack.onFragmentSwapRequested(AuthentificationActivity.SIGNIN_FRAGMENT_ID);
}
});
btnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onRegisterClicked();
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sign_up, container, false);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
private void onRegisterClicked() {
String email = mEmailEdit.getText().toString().trim();
final String pwd = mPasswordEdit.getText().toString().trim();
if(TextUtils.isEmpty(email)) {
Snackbar.make(mCoordinatorLayout,getString(R.string.no_email_entered),Snackbar.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(pwd)) {
Snackbar.make(mCoordinatorLayout,getString(R.string.no_password_entered),Snackbar.LENGTH_LONG).show();
return;
}
mProgressBar.setVisibility(View.VISIBLE);
mAuth.createUserWithEmailAndPassword(email,pwd).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()) {
startActivity(new Intent(getActivity(), MainActivity.class));
getActivity().finish();
}
else {
mProgressBar.setVisibility(View.GONE);
Snackbar.make(mCoordinatorLayout,task.getException().toString(),Snackbar.LENGTH_LONG).show();
}
}
});
}
#Override
public void onDetach() {
super.onDetach();
}
}
I have read many posts about similar problems , some are saying wrap the transaction with a if(!isFinished()) , other are saying to override the onDestroy , none of them worked , and I believe the solution is way simpler .
EDIT :
Here are my SignInFragment and Authentification activity xml :
SignInFragment :
public class SignInFragment extends Fragment {
FragmentSignInBinding signInBinding;
private CoordinatorLayout mCoordinatorLayout;
private EditText mEmailEdit,mPasswordEdit;
private Button btnSignIn,btnSignUp,btnLostPwd;
private ProgressBar mProgressBar;
private FirebaseAuth mAuth;
private SignInFragmentCallBack mCallBack;
public interface SignInFragmentCallBack {
void onFragmentSwapRequested(int FragmentId);
}
public SignInFragment() {}
public static SignInFragment getInstance() {
return new SignInFragment();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mCallBack = (SignInFragmentCallBack) context;
} catch(ClassCastException e) {
throw new ClassCastException(context.toString() + " must implements SignInCallaback");
}
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
signInBinding = DataBindingUtil.setContentView(getActivity(),R.layout.fragment_sign_in);
mEmailEdit = signInBinding.emailSignin;
mPasswordEdit = signInBinding.passwordSignin;
mProgressBar = signInBinding.progressBarSignIn;
btnSignIn = signInBinding.signInButton;
btnSignUp = signInBinding.signUpButton;
btnLostPwd = signInBinding.passwordReset;
mCoordinatorLayout = signInBinding.coordinatorSignin;
mAuth = FirebaseAuth.getInstance();
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signInAction();
}
});
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mCallBack instanceof SignInFragmentCallBack)
mCallBack.onFragmentSwapRequested(AuthentificationActivity.SIGNUP_FRAGMENT_ID);
}
});
btnLostPwd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mCallBack instanceof SignInFragmentCallBack)
mCallBack.onFragmentSwapRequested(AuthentificationActivity.LOST_PWD_FRAGMENT_ID);
}
});
}
private void signInAction() {
String email = mEmailEdit.getText().toString().trim();
final String password = mPasswordEdit.getText().toString().trim();
if(TextUtils.isEmpty(email)) {
Snackbar.make(mCoordinatorLayout,getString(R.string.no_email_entered),Snackbar.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(password)) {
Snackbar.make(mCoordinatorLayout,getString(R.string.no_password_entered),Snackbar.LENGTH_LONG).show();
return;
}
mProgressBar.setVisibility(View.VISIBLE);
mAuth.signInWithEmailAndPassword(email,password).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
mProgressBar.setVisibility(View.GONE);
if(task.isSuccessful()) {
Snackbar.make(mCoordinatorLayout,getString(R.string.login_success),Snackbar.LENGTH_LONG).show();
startActivity(new Intent(getActivity(), MainActivity.class));
getActivity().finish();
}
else
{
Snackbar.make(mCoordinatorLayout,getString(R.string.login_failed),Snackbar.LENGTH_LONG).show();
}
}
});
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sign_in,container,false);
}
#Override
public void onResume() {
super.onResume();
mProgressBar.setVisibility(View.GONE);
}
}
Authentification xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_authentification"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:context="com.example.user.onceuponatime.activity.AuthentificationActivity">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/fragment_container">
</FrameLayout>
</LinearLayout>
EDIT2 : New stack trace :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.onceuponatime, PID: 8674
java.lang.IllegalArgumentException: No view found for id 0x7f0d007f (com.example.user.onceuponatime:id/fragment_container) for fragment SignUpFragment{2b0b994 #1 id=0x7f0d007f signupfragment}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1293)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
SignInFragment xml :
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinator_signin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.user.onceuponatime.fragment.SignInFragment">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#color/colorPrimaryDark"
android:padding="#dimen/activity_horizontal_margin"
>
<ImageView
android:layout_width="#dimen/logo_wh"
android:layout_height="#dimen/logo_wh"
android:src="#mipmap/ic_launcher"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/email_signin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/email_input"
android:textColor="#android:color/white"
android:maxLines="1"
android:inputType="textEmailAddress"
/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:id="#+id/password_signin"
android:inputType="textPassword"
android:imeActionId="#+id/login"
android:imeOptions="actionUnspecified"
android:textColor="#android:color/white"
android:focusableInTouchMode="true"
android:hint="#string/password_input"
/>
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/sign_in_button"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#color/colorAccent"
android:text="#string/short_signin"
android:textColor="#android:color/black"
android:textStyle="bold"
android:textAlignment="center"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/sign_up_button"
android:background="#null"
android:layout_marginTop="20dp"
android:textAllCaps="false"
android:textColor="#color/colorAccent"
android:text="#string/link_register"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/password_reset"
android:background="#null"
android:layout_marginTop="20dp"
android:textAllCaps="false"
android:text="#string/lost_password"
android:textColor="#android:color/white"
android:textSize="15dp"
/>
</LinearLayout>
<ProgressBar
android:id="#+id/progressBarSignIn"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center|bottom"
android:layout_marginBottom="20dp"
android:visibility="gone" />
</android.support.design.widget.CoordinatorLayout>
</layout>
This would be the problem:
mCallBack = new AuthentificationActivity();
You cannot instantiate an Activity with new and have it work correctly. Furthermore, that new instance wouldn't be the current hosting instance anyway.
Instead, you want to cast the current hosting Activity instance to your interface. Since you're using support Fragments, you can use either getActivity() or getContext() to retrieve that instance, as both will return the same object with an Activity host. For example:
mCallBack = (SignUpFragmentCallBack) getContext();
This should be sufficient to at least test with your current setup. A cleaner implementation, however, might be to perform this cast in onAttach() with a try-catch for ClassCastException, where we can throw a more informative Exception if it should fail.
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mCallBack = (SignUpFragmentCallBack) context;
}
catch (ClassCastException e) {
throw new ClassCastException(context.toString() +
" must implement the SignUpFragmentCallBack interface");
}
}
Related
There was such problem: The text which I pass in SelectedActivity simply is not displayed. I have a DrawerLayout with fragments and on click on an element it goes to the SelectedActivity and loads the desired fragment. It works, but the SelectedActivity has a text of Toolbar. It's the one that doesn't show up. I'm new to programming and already completely confused. I would appreciate a solution! Here is my code:
SelectedActivity.java
public class SelectedActivity extends BaseActivity {
private static final String TAG = "SelectedActivity";
private static final String FRAGMENT_NAME = "fragment_name";
public MutableLiveData<String> toolBarTitle = new MutableLiveData<>();
TextView toolbarTitle;
public static void startActivityWithFragment(#NonNull Context context,
#NonNull Class<? extends Fragment> fragmentClass,
#Nullable Bundle bundle) {
context.startActivity(getStartIntent(context, fragmentClass, bundle));
}
private static Intent getStartIntent(#NonNull Context context,
#NonNull Class<? extends Fragment> fragmentClass,
#Nullable Bundle bundle) {
if (bundle == null) {
bundle = new Bundle();
}
bundle.putSerializable(FRAGMENT_NAME, fragmentClass);
Intent intent = new Intent(context, SelectedActivity.class);
intent.putExtras(bundle);
return intent;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_selected);
Toolbar toolbar = findViewById(R.id.selected_activity_toolbar);
toolbarTitle = findViewById(R.id.selected_toolbar_title);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
}
Bundle extras = getIntent().getExtras();
if (extras == null) {
finish();
return;
}
Class<? extends Fragment> fragmentName = (Class<? extends Fragment>) extras.getSerializable(FRAGMENT_NAME);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container_selected_activity, fragmentName, extras)
.commit();
toolBarTitle.observe(this, s -> {
if (s == null) return;
toolbarTitle.setText(s);
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
public void setToolBarTitle(String toolBarTitle){
try {
toolbarTitle.setText(toolBarTitle);
} catch (Exception e) {
e.printStackTrace();
}
}
}
ProfileFragment.java
public class ProfileFragment extends BaseFragment {
private FragmentProfileBinding binding;
public ProfileViewModel profileViewModel;
public View root;
SelectedActivity activity = new SelectedActivity();
public TextView textView;
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
profileViewModel = new ViewModelProvider(this).get(ProfileViewModel.class);
binding = FragmentProfileBinding.inflate(inflater, container, false);
textView = binding.textProfile;
profileViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
root = binding.getRoot();
binding.viewPager2.setAdapter(new ViewPagerAdapter(this));
binding.tabLayout.setTabIconTint(null);
new TabLayoutMediator(binding.tabLayout, binding.viewPager2,
(tab, position) -> {
if (position == 0) {
tab.setText(R.string.posts);
new PostsFragment();
} else {
tab.setText(R.string.saved);
new SavesFragment();
}
}).attach();
activity.setToolBarTitle(getString(R.string.menu_profile));
return root;
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
#Override
public void onResume() {
super.onResume();
}
}
activity_selected.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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/selected_activity_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<TextView
android:id="#+id/selected_toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:elevation="#dimen/dimen_10"
android:textColor="#color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Selected Activity" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="#+id/container_selected_activity"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
This is my first post here. I´m having trouble with a RecyclerView which I´m using into a fragment. I have two different fragments for a BottomNavigationMenu and the items duplicate everytime I get back to the fragment where the RecyclerView is in. I have tried using arraylist.clear(); as it is been suggested many times here but it doesn´t work. I have used the exact same code before using TabLayout with fragments instead of BottomNavigationMenu and it worked fine! the items didn´t duplicate at all... I´m making a music library for an audio streaming app and I´m using realtime firebase to print the information for the RecyclerView onto the screen, if I use: if (audioFileArrayList == null) {
loadData();
} it fixes the issue beacuse this way it doesn´t print the information twice but I don´t think this is a proper solution to this problem. It seems as if everytime I go back to the RecyclerView fragment the view doesn´t refresh but instead it prints everything again and again at the bottom...
This is the MainActivity:
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
getSupportActionBar().hide(); //escondemos la action bar
bottomNavigationView = binding.bottomNavigationID;
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_id, new BibliotecaFragment()).commit();
bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragmentSeleccionado = null;
switch (item.getItemId()) {
case R.id.biblioteca_ID:
fragmentSeleccionado = new BibliotecaFragment();
break;
case R.id.playlists_ID:
fragmentSeleccionado = new PlayListsFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_id, fragmentSeleccionado).commit();
return true;
}
});
}
}
This is the fragment for the library, as I said before if I use
if (audioFileArrayList == null) {
loadData();
}
it stops it from printing it twice.
public class BibliotecaFragment extends Fragment {
FragmentBibliotecaBinding binding;
RecyclerView recyclerView;
AudioFileAdapter audioFileAdapter;
static ArrayList<AudioFile> audioFileArrayList;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentBibliotecaBinding.inflate(getLayoutInflater());
recyclerView = binding.BibliotecaFragmentRecyclerViewID;
recyclerView.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false);
recyclerView.setLayoutManager(manager);
audioFileAdapter = new AudioFileAdapter(getContext());
recyclerView.setAdapter(audioFileAdapter);
loadData();
return binding.getRoot();
}
public void loadData() {
DatabaseReference dbr = FirebaseDatabase.getInstance().getReference();
dbr.child("biblioteca").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
audioFileArrayList = new ArrayList<>();
for (DataSnapshot data : snapshot.getChildren()) {
AudioFile audioFile = data.getValue(AudioFile.class);
audioFileArrayList.add(audioFile);
}
audioFileAdapter.setItems(audioFileArrayList);
audioFileAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
This is my adapter:
public class AudioFileAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
static ArrayList<AudioFile> audioFileList = new ArrayList<>();
public AudioFileAdapter(Context ctx) {
this.context = ctx;
}
public void setItems(ArrayList<AudioFile> audioFile) {
audioFileList.addAll(audioFile);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.audio_item, parent, false);
return new AudioFileViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, #SuppressLint("RecyclerView") int position) {
AudioFileViewHolder audioFileViewHolder = (AudioFileViewHolder) holder;
AudioFile audioFile = audioFileList.get(position);
audioFileViewHolder.txtArtist.setText(audioFile.getArtist());
audioFileViewHolder.txtTitle.setText(audioFile.getTitle());
Glide.with(context).load(audioFile.getImgURL()).into(audioFileViewHolder.imageViewPicture);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putInt("posicion", position);
Intent intent = new Intent(context, Reproductor.class);
intent.putExtras(bundle);
context.startActivity(intent);
}
});
((AudioFileViewHolder) holder).imageViewMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PopupMenu popupMenu = new PopupMenu(context, view);
popupMenu.getMenuInflater().inflate(R.menu.audio_item_popup_menu, popupMenu.getMenu());
popupMenu.show();
popupMenu.setOnMenuItemClickListener((menuItem) -> {
switch (menuItem.getItemId()) {
case R.id.agregar_a_lista_ID: {
break;
}
case R.id.eliminar_de_biblioteca_ID: {
eliminar(position);
break;
}
}
return true;
});
}
});
}
public void eliminar(int position) {
String id = audioFileList.get(position).getId();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
Query delete = databaseReference.child("biblioteca").orderByChild("id").equalTo(id);
delete.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
audioFileList.clear(); // importante limpiar la lista cada vez que se elimina un item para que no se dupliquen en la parte de abajo...
for (DataSnapshot data : dataSnapshot.getChildren()) {
data.getRef().removeValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public int getItemCount() {
return audioFileList.size();
}
public interface ItemClickListener { //interfaz listener para RyclerView
void onItemClick(AudioFile audioFile);
}
}
My ViewHolder:
public class AudioFileViewHolder extends RecyclerView.ViewHolder {
public TextView txtArtist, txtTitle;
public ImageView imageViewPicture, imageViewMenu;
public AudioFileViewHolder(#NonNull View itemView) {
super(itemView);
txtArtist = itemView.findViewById(R.id.artistID);
txtTitle = itemView.findViewById(R.id.titleID);
imageViewPicture = itemView.findViewById(R.id.item_imageID);
imageViewMenu = itemView.findViewById(R.id.item_menu_ID);
}
}
The XML code 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"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/frame_layout_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation_ID" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation_ID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
app:menu="#menu/bottom_navigation_menu" />
</RelativeLayout>
The XML code for RecyclerView:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
tools:context=".BibliotecaFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/BibliotecaFragmentRecyclerViewID"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#3C3A3A"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
And the XML code for each item into the RecyclerView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/audio_itemID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="#color/black"
android:orientation="horizontal">
<ImageView
android:id="#+id/item_imageID"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#drawable/ic_launcher_foreground"
android:padding="5dp" />
<TextView
android:id="#+id/artistID"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:gravity="center"
android:text="Artist"
android:textColor="#color/white" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:gravity="center"
android:text="-"
android:textColor="#color/white" />
<TextView
android:id="#+id/titleID"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:gravity="center"
android:text="Title"
android:textColor="#color/white" />
<ImageView
android:id="#+id/item_menu_ID"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="150dp"
android:background="#drawable/ic_baseline_more_vert"
android:padding="5dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
Sorry for my english, I know it is not perfect, I hope you guys can help me with this.
Rubén.
I'm having the same problem and currently have no answer. You can try my method but only works if your recycler items are definite.
Goto your viewholder class=>
#Override
public int getItemCount() {
return num;
}
Where num is the number of your items in recyclerview.
I've an app with a tab view, which has 2 tab. Tab 2 contains a spinner that has a drop-down function. The spinner includes Prova 1, 2, etc. Clicking on each item will open a fragment below. Clicking on the Prova 1, will take me to a page that show some information, but it doesn't work.
Picture 1
Picture 2
Picture 3
FragmentTop.java
public class FragmentTop extends Fragment { //implements AdapterView.OnItemClickListener{
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private Spinner spinner;
private String[] items;
private FragmentProva1 fragmentProva1;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public FragmentTop() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static FragmentTop newInstance(String param1, String param2) {
FragmentTop fragment = new FragmentTop();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_Top, container, false);
items = getResources().getStringArray(R.array.Top);
fragmentProva1 = new FragmentProva1();
spinner = view.findViewById(R.id.spinnerTop);
initSpinner();
// Inflate the layout for this fragment
return view;
}
private void initSpinner() {
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String text = adapterView.getItemAtPosition(i).toString();
switch (text){
case "Prova1":
setFragment(fragmentProva1);
break;
case "Prova2":
break;
}
Toast.makeText(adapterView.getContext(),text,Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void setFragment(Fragment fragment){
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragmentTop_id, fragment);
fragmentTransaction.commit();
}
}
fragment_top.xml
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".FragmentTop">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Spinner
android:id="#+id/spinnerTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16sp"
android:textSize="16sp"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragmentTop_id" />
</ScrollView>
</LinearLayout>
</FrameLayout>
FragmentProva1.java
public class FragmentProva1 extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private TextInputLayout textInputSideA;
private TextInputLayout textInputSideB;
private TextInputLayout textInputSideC;
private TextView result;
private Button btnCalculate;
private LinearLayout Prova1LinearLayout;
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public FragmentProva1() {
// Required empty public constructor
}
public static FragmentProva1 newInstance(String param1, String param2) {
FragmentProva1 fragment = new FragmentProva1();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_prova1, container, false);
textInputSideA = view.findViewById(R.id.textInputSideA);
textInputSideB = view.findViewById(R.id.textInputSideB);
textInputSideC = view.findViewById(R.id.textInputSideC);
result = view.findViewById(R.id.result);
Prova1LinearLayout = view.findViewById(R.id.Prova1LinearLayout);
btnCalculate = view.findViewById(R.id.btnCalculate);
btnCalculate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
double info1;
double info2;
double info3;
if(!validateLatoA() | !validateLatoB() | !validateLatoC()){
return;
}
info1 = calculate();
}
});
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
private boolean validateLatoA(){
String latoA_Input = textInputSideA.getEditText().getText().toString().trim();
if(latoA_Input.isEmpty()){
textInputSideA.setError("Field can't be empty");
return false;
} else {
textInputSideA.setError(null);
return true;
}
}
private boolean validateLatoB(){
String latoB_Input = textInputSideB.getEditText().getText().toString().trim();
if(latoB_Input.isEmpty()){
textInputSideB.setError("Field can't be empty");
return false;
} else {
textInputSideB.setError(null);
return true;
}
}
private boolean validateLatoC(){
String latoC_Input = textInputSideC.getEditText().getText().toString().trim();
if(latoC_Input.isEmpty()){
textInputSideC.setError("Field can't be empty");
return false;
} else {
textInputSideC.setError(null);
return true;
}
}
}
fragment_prova1.xml
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".FragmentProva1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="UselessParent"
android:padding="16sp"
android:layout_marginTop="16sp"
android:id="#+id/Prova1LinearLayout">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputSideA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="info1"
android:textSize="16sp"
android:inputType="numberDecimal"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputSideB"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="info2"
android:textSize="16sp"
android:inputType="numberDecimal"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputSideC"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="info3"
android:textSize="16sp"
android:inputType="numberDecimal"/>
</com.google.android.material.textfield.TextInputLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Calculate"
android:textSize="16sp"
android:id="#+id/btnCalculate"/>
<TextView
android:id="#+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="16sp"
android:padding="16dp"/>
</LinearLayout>
</FrameLayout>
I have a problem ,I create recyclerview and its work fine at the first search data from api , it display fine but when I try to search with new data ( second time ) it is not display anything i try to test and debug every every thing work fine and new data enter to adapter and get the result fine and set adapter to recyclerview but it is not showing any thing
I try several method like use only one adapter and change it's list of Date and use notifyDataSetChange but not work still only show at the first time
Below activity is use to search get date ( use in searching data )
fromDate to toDate
DeliveryReportActivity.java
public class DeliveryReportActivity extends AppCompatActivity
implements DateDialogFromFragment.SelectDateFromInterface,
DateDialogToFragment.SelectDateToInterface {
Button btn_from;
Button btn_to;
EditText et_fromDate;
EditText et_toDate;
Button search_btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delivery_report);
btn_from=(Button)findViewById(R.id.btn_fromDate);
btn_to=(Button)findViewById(R.id.btn_toDate);
et_fromDate = (EditText) findViewById(R.id.from_date);
et_toDate = (EditText) findViewById(R.id.to_date);
search_btn=(Button)findViewById(R.id.search_delivery_report_btn);
et_fromDate.setText(new SimpleDateFormat("yyyy-MM-dd").format(new
Date()));
et_toDate.setText(new SimpleDateFormat("yyyy-MM-dd").format(new
Date()));
btn_from.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DateDialogFromFragment dateDialogFragment = new
DateDialogFromFragment();
android.app.FragmentTransaction ft =
getFragmentManager().beginTransaction();
dateDialogFragment.show(ft, "DatePicker");
}
});
btn_to.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DateDialogToFragment dateDialogFragment = new
DateDialogToFragment();
android.app.FragmentTransaction ft =
getFragmentManager().beginTransaction();
dateDialogFragment.show(ft, "DatePicker");
}
});
search_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bundle bundle=new Bundle();
bundle.putString("from",et_fromDate.getText().toString()+ "
00:00:00");
bundle.putString("to",et_toDate.getText().toString()+" 23:59:59");
Intent intent =new
Intent(DeliveryReportActivity.this,DeliveryReportListActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
});
}
#Override
public void onGetSelectFromDate(String fromDate) {
et_fromDate.setText(fromDate);
}
#Override
public void onGetSelectToDate(String toDate) {
et_toDate.setText(toDate);
}
}
and it's view activity_delivery_report.xml
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:layout_margin="20dp"
android:orientation="vertical"
tools:context="com.exatech.groupsmsandroid.activity.
deliveryReport.DeliveryReportActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/btn_fromDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/From"
android:textSize="18dp" />
<EditText
android:id="#+id/from_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2017-12-26" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:orientation="horizontal">
<Button
android:id="#+id/btn_toDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/to" />
<EditText
android:id="#+id/to_date"
android:text="2017-12-26"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_centerInParent="true"
android:gravity="center"
android:layout_marginTop="20dp"
android:id="#+id/search_delivery_report_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:text="#android:string/search_go" />
</RelativeLayout>
</LinearLayout>
after I press the search button it's start new activity that show my recylerview the new activity is
DeliveryReportListActivity .java
public class DeliveryReportListActivity extends AppCompatActivity implements
DeliveryReportService.DeliveryReportServiceInterface {
private static final String TAG = "GSMS";
private Bundle bundle;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delivery_report_list);
recyclerView = (RecyclerView) findViewById(R.id.delivery_report_rv);
}
#Override
protected void onResume() {
super.onResume();
bundle = getIntent().getExtras();
String from = bundle.getString("from");
String to = bundle.getString("to");
DeliveryReportService.getInstance(this).
getDeliveryReportFromDateToDate(from, to);// Call api get deliver
}
#Override
public void onGetDeliveryReport(Response<List<DeliveryReportResource>>
listResponse) {// response
Log.i(TAG, "onGetDeliveryReport: listResponse.body():" +
listResponse.body());
DeliveryReportAdapter deliveryReportAdapter = new
DeliveryReportAdapter(DeliveryReportListActivity.this, listResponse.body());
recyclerView.setAdapter(deliveryReportAdapter);
deliveryReportAdapter.notifyDataSetChanged();
Toast.makeText(DeliveryReportListActivity.this, "Delivery Report Success
", Toast.LENGTH_SHORT).show();
}
#Override
public void onDeliveryConnectionFailed() {
Toast.makeText(DeliveryReportListActivity.this, "Connect Error ",
Toast.LENGTH_SHORT).show();
}
}
and it's view activity_delivery_report_list.xml
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:orientation="vertical"
tools:context="com.exatech.groupsmsandroid.activity.deliveryReport.
DeliveryReportListActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:text="#string/text"
android:layout_weight="3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_weight="4"
android:text="#string/phone_no"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_weight="4"
android:text="#string/status"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/delivery_report_rv"
android:layout_width="match_parent"
app:layoutManager="LinearLayoutManager"
android:layout_height="match_parent"
tools:listitem="#layout/delivery_report_list_content"/>
</LinearLayout>
Below is Myadapter Class
**DeliveryReportAdapter.java**
public class DeliveryReportAdapter extends
RecyclerView.Adapter<DeliveryReportAdapter.ViewHolder> {
List<DeliveryReportResource> listDeliveryReport;
Context context;
public DeliveryReportAdapter(Context context, List<DeliveryReportResource>
listDeliveryReport) {
this.listDeliveryReport = listDeliveryReport;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =
LayoutInflater.from(parent.getContext()).
inflate(R.layout.delivery_report_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.item = listDeliveryReport.get(position);
holder.text.setText(holder.item.getText());
CustomAdapterFroDeliveryReport adapterFroDeliveryReport = new
CustomAdapterFroDeliveryReport(context, R.layout.two_text_contect,
listDeliveryReport.get(position).getSmsSubscribedRecipientsResourceList());
holder.phoneNoAndStatus.setAdapter(adapterFroDeliveryReport);
holder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "click message no=" +
holder.item.getText(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return listDeliveryReport.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
View view;
TextView text;
ListView phoneNoAndStatus;
DeliveryReportResource item;
public ViewHolder(View itemView) {
super(itemView);
view = itemView;
text = (TextView) itemView.findViewById(R.id.message_tv);
phoneNoAndStatus = (ListView)
itemView.findViewById(R.id.phoneNo_and_status_lv);
}
}
}
Try to create an adapter once and then update items
Add next code to your adapter class
ArrayList<DeliveryReportResource> listDeliveryReport = new ArrayList<DeliveryReportResource>();
public DeliveryReportAdapter(Context context) {
this.context = context;
}
public void updateItems(List<DeliveryReportResource> list) {
listDeliveryReport.clear();
listDeliveryReport.addAll(list);
notifyDataSetChanged();
}
Then create adapter once in onCreate() and place it as global variable
And now you should call adapter.updateItems(...) every time you want to change data
I have added tab layout in my activity.Everything is working fine, but the tab Indicators are not showing up as expected. I am adding the photo below so that you can get an idea.I mean to say that when I click on Overview(tab indicator is shown below Detail fragment) and vice versa.
Given below is the XML code(Activity_inventory_detail):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_inventory_detail_"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.fafaldo.fabtoolbar.widget.FABToolbarLayout
android:id="#+id/fabtoolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:containerId="#+id/fabtoolbar_container"
app:fabId="#+id/fabtoolbar_fab"
app:fabToolbarId="#+id/fabtoolbar_toolbar"
app:fadeInFraction="0.2"
app:hideDuration="200"
app:horizontalMargin="16dp"
app:showDuration="600"
app:verticalMargin="16dp">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="35dp"
android:background="#color/colorPrimary"
app:tabGravity="fill"
app:tabIndicatorColor="#color/white"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#color/white" />
<com.aaryanapps.hub.ui.controls.LockableViewPager
android:id="#+id/pager_inventory_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tab_layout"
android:background="#color/white"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<RelativeLayout
android:id="#+id/fabtoolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true">
<android.support.design.widget.FloatingActionButton
android:id="#+id/fabtoolbar_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/abc_ic_menu_share_mtrl_alpha"
app:backgroundTint="#color/colorPrimary"
app:fabSize="mini" />
</RelativeLayout>
<LinearLayout
android:id="#+id/fabtoolbar_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
app:backgroundTint="#color/colorPrimary">
<ImageView
android:id="#+id/one"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="centerInside"
android:src="#drawable/abc_ic_menu_share_mtrl_alpha" />
<ImageView
android:id="#+id/two"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="centerInside"
android:src="#drawable/ic_menu_gallery_white" />
<ImageView
android:id="#+id/three"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:backgroundTint="#color/tranperent_white"
android:scaleType="centerInside"
android:src="#drawable/ic_menu_camera_white" />
</LinearLayout>
</com.github.fafaldo.fabtoolbar.widget.FABToolbarLayout>
</RelativeLayout>
Java Code(Inventory_deatil_Activity.java) is given below(can not post full code as it is having many lines), only adding Tablayout and the related part. This is code in which I declared the Tablayout .
public class Inventory_detail_Activity extends AbstractKActivity implements DetailsDataListener, View.OnClickListener,
SimpleGestureFilter.SimpleGestureListener,
ContentManager.PickContentListener {
public static final String TAG_LABEL_OVERVIEW = "Overview";
public static final String TAG_LABEL_DETAILS = "Detail";
InventoryItemsList inventoryItems;
protected int current_item_index = 0;
public List<InventoryItem> inventory_items_list = new ArrayList<>();
InventoryItem inventory_item;
private ViewPager viewPager;
private ViewPagerAdapter pagerAdapter;
TabLayout tabLayout;
this is where I have initialized the Tablayout .
protected void init() {
final TabLayout tabLayout = (TabLayout)findViewById(R.id.tab_layout);
viewPager = (ViewPager) findViewById(R.id.pager_inventory_detail);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#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) {
}
});
Given below is the code for ViewPagerAdapter
class ViewPagerAdapter extends SmartFragmentStatePagerAdapter<ItemDetailAbstractFragment> {
//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) {
ItemDetailAbstractFragment caf;
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
caf = new ItemDetailOverviewFragment();
break;
case 1: // Fragment # 0 - This will show FirstFragment different title
caf = new ItemDetailDetailsFragment();
break;
default:
return null;
}
Bundle args = ActivityStateManager.getInstance().getActivityState(getLocalClassName());
if (args == null) {
args = new Bundle();
}
caf.setFlowItem(inventory_item);
if(current_item_index == -1) {
caf.setFlowItem(inventory_item);
caf.populateData();
}
return caf;
}
#Override
public int getCount() {
return 2;
}
public void addFragment(int position, String title) {
mFragmentTitleList.add(position, title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
#Override
public void onPause() {
Log.e("DEBUG", "onPause of ClientListTabactivity");
super.onPause();
// currentState.putSerializable("flowItem",inventory_item);
// ActivityStateManager.getInstance().updateActivityState(getLocalClassName(), currentState);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// outState.putSerializable("flowItem",inventory_item);
// ActivityStateManager.getInstance().updateActivityState(getLocalClassName(), outState);
contentManager.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
contentManager.onRestoreInstanceState(savedInstanceState);
}
private void setupViewPager(ViewPager viewPager) {
pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
pagerAdapter.addFragment(0, TAG_LABEL_OVERVIEW);
pagerAdapter.addFragment(1, TAG_LABEL_DETAILS);
viewPager.setAdapter(pagerAdapter);
//updateFragmentsForFlowItem();
}
[Edited]:
this is the AbstractActivity code:
public class AbstractKActivity extends AppCompatActivity {
protected int content_view = 0;
protected String mTitle = "";
protected TextView title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prepareInit();
if (content_view != 0) {
setContentView(content_view);
}
initToolbar();
processIntent();
init();
}
protected void initToolbar() {
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.custom_actionbar);
title=(TextView)findViewById(getResources().getIdentifier("action_bar_title", "id", getPackageName()));
title.setText(mTitle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// getSupportActionBar().setTitle(mTitle);
}
protected void processIntent() {
}
protected void init() {
}
protected void prepareInit() {
}
protected void setToolbarTitleText(String titleText) {
mTitle = titleText;
title.setText(titleText);
}
}
At first Modify your CODE. Don't return null; . You should return your Default Fragment .
Don't
case 1: // Fragment # 0 - This will show FirstFragment different title
caf = new ItemDetailDetailsFragment();
break;
default:
return null;
Do
#Override
public Fragment getItem(int position) {
ItemDetailAbstractFragment caf;
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
caf = new ItemDetailOverviewFragment();
break;
case 1: // Fragment # 0 - This will show FirstFragment different title
caf = new ItemDetailDetailsFragment();
break;
default:
return new ItemDetailOverviewFragment();
}
Secondly
viewPager = (ViewPager) findViewById(R.id.pager_inventory_detail);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(0); // Declare this
EDIT
public void onTabSelected(TabLayout.Tab tab) {
tab.select();
}