I have a question that how to get the image from a real-time database. In my code, I want to get the data from the database ( one is text form, one is image form ) and insert them in the recycler view. I get the reference from the internet and find these codes to realise my function. However, after inserting it, it still cannot be shown because my image is in string form but I cannot find any solution to solve it. Can somebody help me? Maybe the main problem is I do not know how to insert the URL of the real-time database.
Problem faced :
java.lang.ClassCastException: com.google.android.material.imageview.ShapeableImageView cannot be cast to android.widget.TextView
at com.example.assignment_mad.NotificationAdapter$MyViewHolder.<init>(Notificatiion_Adapter.kt:118)
at com.example.assignment_mad.NotificationAdapter.onCreateViewHolder(Notificatiion_Adapter.kt:85)
at com.example.assignment_mad.NotificationAdapter.onCreateViewHolder(Notificatiion_Adapter.kt:63)
Main code :
package com.example.assignment_mad
import android.content.ContentValues.TAG
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.example.assignment_mad.databinding.ActivityMainBinding
import com.example.assignment_mad.databinding.FragmentNotificationBinding
import com.example.assignment_mad.databinding.FragmentSearchPageBinding
import com.google.android.material.imageview.ShapeableImageView
import com.google.android.material.tabs.TabLayout
import com.google.firebase.database.*
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
import kotlinx.android.synthetic.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_notification_.*
class Notification_Fragment : Fragment( ) {
val database=Firebase.database
val myRef=database.getReference("message")
private var _binding:FragmentNotificationBinding?=null
private val binding get()=_binding!!
private lateinit var dbref: DatabaseReference
private lateinit var newRecyclerView: RecyclerView
private lateinit var newArrayList: ArrayList<Company>
private lateinit var tempArrayList: ArrayList<Company>
lateinit var imageId:Array<Int>
lateinit var heading:Array<String>
lateinit var news:Array<String>
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<NotificationAdapter.MyViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var views =inflater.inflate(R.layout.fragment_notification_, container, false)
newRecyclerView=views.findViewById(R.id.recyclerView)
newArrayList= arrayListOf<Company>()
// Inflate the layout for this fragment
return views
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
super.onViewCreated(itemView, savedInstanceState)
adapter=NotificationAdapter(newArrayList)
getUserdata()
}
private fun getUserdata() {
dbref=FirebaseDatabase.getInstance("https://recyclerview-e3e96-default-rtdb.asia-southeast1.firebasedatabase.app/").getReference("Notification")
dbref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()){
for (companySnapshot in snapshot.children){
val company=companySnapshot.getValue(Company::class.java)
newArrayList.add(company!!)
}
adapter?.notifyDataSetChanged()
}
}
override fun onCancelled(error: DatabaseError) {
Log.w(TAG, "Failed to read value.", error.toException())
}
})
newRecyclerView.layoutManager=LinearLayoutManager(activity)
newRecyclerView.setHasFixedSize(true)
newRecyclerView.adapter=adapter
}
}
The recyclerview adapter :
package com.example.assignment_mad
import android.provider.Settings.System.getString
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.imageview.ShapeableImageView
import kotlinx.android.synthetic.main.dropdown_item.view.*
class NotificationAdapter(private val companysList:ArrayList<Company>):RecyclerView.Adapter<NotificationAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView=LayoutInflater.from(parent.context).inflate(R.layout.list_item,parent,false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem=companysList[position]
holder.titleImage.text=currentItem.titleImage
//holder.titleImage.setImageResource(currentItem.titleImage)
holder.tvHeading.text=currentItem.heading
}
override fun getItemCount(): Int {
return companysList.size
}
class MyViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
//original
//val titleImage:ShapeableImageView=itemView.findViewById(R.id.title_image)
val titleImage: TextView =itemView.findViewById(R.id.title_image)
val tvHeading: TextView =itemView.findViewById(R.id.tvHeading)
}
}
the xml file and list_item 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"
android:background="#color/white"
tools:context=".Notification_Fragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerView"
tools:listitem="#layout/list_item"/>
<!-- TODO: Update blank fragment layout -->
</FrameLayout>
------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="8dp">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/title_image"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="#style/RoundCorner"
android:src="#drawable/company_logo_1"/>
<TextView
android:id="#+id/tvHeading"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Candidate Biden Called Saudi Arable a Pareft eaft."
android:textSize="16dp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/title_image"
app:layout_constraintTop_toTopOf="parent"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_image"
android:background="#color/underline"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The realtime firebase resource :
enter image description here
The specific error you are seeing is because you define a ShapeableImageView in xml with id title_image, but you are casting it to a TextView in this line:
val titleImage: TextView =itemView.findViewById(R.id.title_image)
Once you resolve this, consider using an image loading library like Glide to load the image URL you get from the Realtime Database into your ImageView.
Related
I have a view (activity_SingIn) and its Presenter now in the onCreate method gives me the following error related to "singInPresenter.singInUser(v);"
2022-09-18 17:30:51.785 3811-3811/com.example.Natour21 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.Natour21, PID: 3811
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.NaTour21.Presenter.Activity.SingInPresenter.singInUser(android.view.View)' on a null object reference
at com.example.NaTour21.View.Activity.activity_singIn$2.onClick(activity_singIn.java:61)
package com.example.NaTour21.Presenter.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Handler;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.example.NaTour21.View.Activity.activity_Home;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import android.widget.ProgressBar;
public class SingInPresenter extends AppCompatActivity {
private EditText EmailLgn,PasswordLgn;
String[] messaggio = {"Campi vuoti inserili"};
private ProgressBar progressBar;
public void singInUser(View view) {
String email = EmailLgn.getText().toString();
String password = PasswordLgn.getText().toString();
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
progressBar.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
home();
}
}, 3000);
} else {
String error;
try{
throw task.getException();
}catch(Exception e){
error ="Errore di accesso utente";
}
Snackbar snackbar = Snackbar.make(view,error,Snackbar.LENGTH_SHORT);
snackbar.setBackgroundTint(Color.WHITE);
snackbar.setTextColor(Color.BLACK);
snackbar.show();
}
}
});
}
public void home() {
Intent intent = new Intent(this, activity_Home.class);
startActivity(intent);
finish();
}
#Override
public void onStart() {
super.onStart();
FirebaseUser UtenteCorrente = FirebaseAuth.getInstance().getCurrentUser();
if(UtenteCorrente != null){
home();
}
}
}
package com.example.NaTour21.View.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import com.example.NaTour21.Presenter.Activity.SingInPresenter;
import com.example.NaTour21.R;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
import android.widget.ProgressBar;
public class activity_singIn extends AppCompatActivity{
private EditText EmailLgn,PasswordLgn;
private Button loginLgn;
private Button registratiLgn;
private SingInPresenter singInPresenter;
private ProgressBar progressbar;
String[] messaggio = {"Campi vuoti inserirli",
"Accesso effettuato con successo",
"Formato email non valido",
"La password deve avere minimo 6 caratteri"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_singin);
getSupportActionBar().hide();
initializeComponent();
registratiLgn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(activity_singIn.this, activity_singUp.class);
startActivity(intent);
}
});
loginLgn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String email = EmailLgn.getText().toString();
String password = PasswordLgn.getText().toString();
if (email.isEmpty() || password.isEmpty()) {
Snackbar snackbar = Snackbar.make(v, messaggio[0], Snackbar.LENGTH_SHORT);
snackbar.setBackgroundTint(Color.WHITE);
snackbar.setTextColor(Color.BLACK);
snackbar.show();
} else if (!isValidEmail(email)) {
Snackbar snackbar = Snackbar.make(v, messaggio[2], Snackbar.LENGTH_SHORT);
snackbar.setBackgroundTint(Color.WHITE);
snackbar.setTextColor(Color.BLACK);
snackbar.show();
}else if (!(password.length() < 6)) {
Snackbar snackbar = Snackbar.make(v, messaggio[3], Snackbar.LENGTH_SHORT);
snackbar.setBackgroundTint(Color.WHITE);
snackbar.setTextColor(Color.BLACK);
snackbar.show();
}else{
Snackbar snackbar = Snackbar.make(v, messaggio[1], Snackbar.LENGTH_SHORT);
snackbar.setBackgroundTint(Color.WHITE);
snackbar.setTextColor(Color.BLACK);
snackbar.show();
singInPresenter.singInUser(v); //??????
}
}
});
}
private boolean isValidEmail(String email) {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
private void initializeComponent() {
registratiLgn = findViewById(R.id.btRegistratiLgn);
EmailLgn = findViewById(R.id.tilEmailLgn);
PasswordLgn = findViewById(R.id.tilPasswordLgn);
loginLgn = findViewById(R.id.btLoginLgn);
progressbar = findViewById(R.id.progressbarLgn);
}
}
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/sfondo"
android:id="#+id/activity_singin"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="336dp"
android:layout_height="196dp"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/txtNomeApp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:clickable="true"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="NaTour21"
android:textColor="#color/white"
android:textSize="60sp" />
</LinearLayout>
<LinearLayout
android:layout_width="361dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<EditText
android:id="#+id/tilEmailLgn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="25dp"
android:drawableLeft="#drawable/ic_email"
android:ems="10"
android:hint="Email"
android:textColor="#color/white"
android:inputType="textEmailAddress"
app:backgroundTint="#color/white"/>
<EditText
android:id="#+id/tilPasswordLgn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:drawableLeft="#drawable/ic_password"
android:drawableRight="#drawable/ic_occhio"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:textColor="#color/white"
app:backgroundTint="#color/white"/>
<ProgressBar
android:id="#+id/progressbarLgn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_constraintTop_toBottomOf="#id/containerComponents" />
<Button
android:id="#+id/btLoginLgn"
android:layout_width="232dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="30dp"
android:background="#drawable/button_login"
android:text="Login"
android:textColor="#color/white"
android:textSize="16sp"
android:textStyle="bold"/>
<Button
android:id="#+id/btRegistratiLgn"
android:layout_width="232dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:background="#drawable/button_registrati"
android:text="Registrati"
android:textColor="#color/white"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
Dear #Fabiola Salomone if you are trying to use MVP because you said you have a presenter then i am afraid you are not doing it correctly at least according to what i know about MVP please study about it that will be better instead of me or anyone else telling you the code directly because you will not know how it works that way , for a head start you need to make an interface and presenter and inside that presenter you will make three more interfaces View Model and Presenter again and then you will initialize that presenter inside you main activity , here you are extending you presenter with appcompactActivty that itself is wrong a lot about your code is wrong its not MVP by any means so i don't how can i help you exactly with this apart from what i just said, Once you know how MVP work then me or other users can surely help you with this, Still if you need any clearance you can ask :)
I am new in android studio and I hope that the question is not too trivial. I have been searching for several days to find an official solution for multiple back stacks in java script. Take a simple project I have, a bottom navigation with two items, item_home and item_users. like below:
My bottom navigation bar
This is the activity_main.xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_nav_menu"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And I have two navigation graph for home and users items, selected programicaly in the MainActivity.java. Here is the MainActivity.java :
package com.example.testnavigationgraph;
import static androidx.navigation.fragment.NavHostFragment.findNavController;
import static androidx.navigation.ui.NavigationUI.setupActionBarWithNavController;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentContainerView;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.NavOptions;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
public class MainActivity extends AppCompatActivity {
private Bundle bundle;
private Fragment fragment;
FragmentManager fragmentManager;
BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigationView = findViewById(R.id.bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(bOnClickListener);
bottomNavigationView.setSelectedItemId(R.id.item_home);
}
///////////////////Bottom Navigation//////////////////////////////
private BottomNavigationView.OnNavigationItemSelectedListener
bOnClickListener =new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.item_home:
Navigation.findNavController(MainActivity.this,R.id.nav_host_fragment).setGraph(R.navigation.nav_graph);
return true;
case R.id.item_users:
Navigation.findNavController(MainActivity.this,R.id.nav_host_fragment).setGraph(R.navigation.nav_graph2);
return true;
}
return false;
}
};
}
Please make a fast, simple solution for this controversial and widely used issue in java script.
i had a code where i used kotlin syntetic and it didnt work enymore on my app i have an error that is " lateinit property binding has not been initialized" i hanged added only private lateinit var binding: ActivityMainBinding and i changed the uzytkownik.text = sb.toString() to binding.uzytkownik.text = sb.toString() becouse that what i have found what to do but the rest of private fun retrivePerson() is harder to me
my collection name what i wanna to show in firebase is uzytkownik
this is my code
package com.example.nfc
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.widget.Button
import android.widget.ScrollView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.nfc.databinding.ActivityMainBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.ktx.toObject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.tasks.await
import java.lang.StringBuilder
class MainActivity : AppCompatActivity() {
private val personCollectionName = Firebase.firestore.collection("uzytkownik")
private lateinit var binding: ActivityMainBinding
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
auth = Firebase.auth
val addButton = findViewById<Button>(R.id.addButton)
addButton.setOnClickListener {
val intent = Intent(this, addtrasa::class.java)
startActivity(intent)
}
val btnRetrieveData = findViewById<Button>(R.id.btnRetrieveData)
btnRetrieveData.setOnClickListener {
retrivePerson()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
auth.signOut()
val logoutIntent = Intent(this, loginActivity::class.java)
logoutIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(logoutIntent)
Toast.makeText(this, "ZostaĆes wylogowany", Toast.LENGTH_SHORT).show()
return super.onOptionsItemSelected(item)
}
private fun retrivePerson() = CoroutineScope(Dispatchers.IO).launch {
try {
val querySnapshot = personCollectionName.get().await()
val sb = StringBuilder()
for (document in querySnapshot.documents) {
val users = document.toObject<users>()
sb.append("$users\n")
}
withContext(Dispatchers.Main) {
binding.uzytkownik.text = sb.toString()
}
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(this#MainActivity, e.message, Toast.LENGTH_LONG).show()
}
}
}
}
my scrollview where i wanna it o show its
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="245dp"
android:layout_height="66dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/uzytkownik"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Witaj,"
android:textColor="#android:color/black"
android:textSize="18sp" />
</ScrollView>
I am stucked at one problem regarding my fragments. I just want to switch between different fragments and show a menu on the top - quite standard I think - smth. like here:
For this purpose I set up a PageAdapter (where SMartFragmentStatePageAdapter is just derived from FragmentStatePagerAdapter):
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
class ViewPagerAdapter extends SmartFragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
#Override
public int getCount() {
return categories.length;
}
#Override
public CharSequence getPageTitle(int position) {
return categories[position];
}
}
I initializing the page adapter in my main class:
viewPager = (ViewPager) findViewById(R.id.pager);
SmartFragmentStatePagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
And my ArrayFragment Class looks like this:
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.Collections;
public class ArrayListFragment extends ListFragment {
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
public static ArrayListFragment newInstance(int num) {
ArrayListFragment f = new ArrayListFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
int page = getArguments().getInt("num", -1);
((TextView)tv).setText("Fragment #" + mNum);
return v;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, Collections.singletonList("test1")));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
Now the weired thing is, that for showing up the heading titles in of the PageAdapter I need to add the "PagerTabStrip" in my layout file - so my layout file for my main class looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.PagerTabStrip>
</android.support.v4.view.ViewPager>
<LinearLayout android:orientation="horizontal"
android:gravity="center" android:measureWithLargestChild="true"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="0">
<Button android:id="#+id/goto_first"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="first">
</Button>
<Button android:id="#+id/goto_last"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="last">
</Button>
</LinearLayout>
</LinearLayout>
The Problem now is, when I am using the PagerTabStrip, then the content of the ArrayFragment is not shown up:
With the PagerTabStrip:
Without the PagerTabStrip:
So without the PagerTabStrip the content is shown and I do not know why.
I read here that the solution might be to use getChildFragmentManager() instead of getSupportFragmentManager(). But this function can only be used if my main class derives from Fragment, but it derives from FragmentActivity so this can not be the solution for me.
Any ideas?
I found out in the meanwhile what went wrong.
I was pretty sure, that there has to be a problem in the layout file and indeed it was. Probably I should not have set the android:layout_height="0px" :) Result of hours of hacking without break.
So with small adaptions of the ViewPager it worked like a charme:
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp">
</android.support.v4.view.PagerTabStrip>
</android.support.v4.view.ViewPager>
Thanks everybody who has started analyzing already!
I am making a tabbed activity with multiple fragments which populate themselves with RecyclerView and the data for this is being retrieved from Firebase Realtime database and Storage as backend.
The error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.visan.peds, PID: 1522
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference
at com.example.visan.peds.Landing_mother.getData(Landing_mother.java:76)
at com.example.visan.peds.Landing_mother.onCreateView(Landing_mother.java:43)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2087)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1113)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1295)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1643)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:679)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1272)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1120)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1646)
at android.view.View.measure(View.java:18991)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:716)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:462)
at android.view.View.measure(View.java:18991)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:18991)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18991)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18991)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18991)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2645)
at android.view.View.measure(View.java:18991)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2403)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1342)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1591)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1233)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6552)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:919)
at android.view.Choreographer.doCallbacks(Choreographer.java:710)
at android.view.Choreographer.doFrame(Choreographer.java:645)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:905)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5582)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
My Main Activity, Landing.java
package com.example.visan.peds;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
public class Landing extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_landing);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout=(TabLayout)findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("CHILD"));
tabLayout.addTab(tabLayout.newTab().setText("MOTHER"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager=(ViewPager) findViewById(R.id.pager);
final Landing_frag_manager frag_manager=new Landing_frag_manager(getSupportFragmentManager(),tabLayout.getTabCount(),Landing.this);
viewPager.setAdapter(frag_manager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
#Override
public void onTabReselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
});
}
}
Its layout file, activity_landing.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/main_layout"
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=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
</RelativeLayout>
The fragment adapter, Landing_frag_manager.java
package com.example.visan.peds;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class Landing_frag_manager extends FragmentPagerAdapter {
private int num_of_tabs;
Context context;
public Landing_frag_manager(FragmentManager fm, int numOfTabs, Context context){
super(fm);
this.num_of_tabs=numOfTabs;
this.context=context;
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
Landing_child child=new Landing_child();
return child;
case 1:
Landing_mother mother=new Landing_mother();
return mother;
default:
return null;
}
}
#Override
public int getCount() {
return num_of_tabs;
}
}
Code for Fragment, Landing_mother.java
package com.example.visan.peds;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class Landing_mother extends Fragment {
private List<Ailment> ailments;
private RecyclerView recyclerView;
LinearLayoutManager layoutManager;
private RecyclerView.Adapter adapter;
public Landing_mother(){}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view=inflater.inflate(R.layout.fragment_landing_mother,container,false);
ailments=new ArrayList<>();
getData();
recyclerView =(RecyclerView)view.findViewById(R.id.recyclerView1);
recyclerView.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
return view;
}
private void getData(){
FirebaseDatabase db=FirebaseDatabase.getInstance();
DatabaseReference ref=db.getReference().child("Mother").child("0");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
Log.v("SNAPSHOT::",dataSnapshot.toString());
for (DataSnapshot snapshot:dataSnapshot.getChildren()){
Ailment ailment=snapshot.getValue(Ailment.class);
ailments.add(ailment);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
adapter=new LandingAdapter(ailments,getActivity());
recyclerView.setAdapter(adapter);
}
}
Its layout file, fragment_landing_mother.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:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
The Ailment object class, Ailment.java
package com.example.visan.peds;
public class Ailment {
private String name, image_url;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setImage_url(String image_url){
this.image_url=image_url;
}
public String getImage_url(){
return image_url;
}
}
Adapterfor RecyclerView, LandingAdapter.java
package com.example.visan.peds;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.firebase.ui.storage.images.FirebaseImageLoader;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import java.util.List;
public class LandingAdapter extends RecyclerView.Adapter<LandingAdapter.ViewHolder>{
private List<Ailment> list;
private Context context;
FirebaseStorage storage;
LayoutInflater inflater;
public LandingAdapter(List<Ailment> list, Context context){
super();
this.list=list;
this.context=context;
inflater=LayoutInflater.from(context);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.landing_list_row,parent,false);
ViewHolder viewHolder=new ViewHolder(itemView);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Ailment ailment=list.get(position);
StorageReference storageReference=storage.getReferenceFromUrl(ailment.getImage_url());
Glide.with(context).using(new FirebaseImageLoader()).load(storageReference).into(holder.imageView);
holder.textView.setText(ailment.getName());
}
#Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public ImageView imageView;
public TextView textView;
public ViewHolder(View view){
super(view);
imageView=(ImageView)view.findViewById(R.id.row_image);
textView=(TextView)view.findViewById(R.id.row_name);
}
}
}
Layout file for Single Row of recyclerView, landing_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/row_image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/row_name"
android:layout_below="#+id/row_image"/>
</RelativeLayout>
Your are calling getData(); which is trying to access RecyclerView before it has been initialised. Call it after you finish recycler view initialisation. For example after recyclerView.setLayoutManager(layoutManager);