I have a TextView in the navigation drawer of my app. When initially loading the relevant xml, the TextView (displaying users name and surname) runs fine without an error. However, after navigating to the next activity and returning immediately back to the previous activity the app crashes with a NullPointerException. Why does it load it successfully initially but crashes when navigating back? I have put in a null check but this just sets the TextView's to blank but prevents the crashing.
My navigation header 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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="117dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
app:srcCompat="#drawable/logo" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<TextView
android:id="#+id/textView15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:textSize="24sp" />
<TextView
android:id="#+id/textView40"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
Part of the layout xml where i am referencing the navigation header:
<com.google.android.material.navigation.NavigationView
android:id="#+id/mydeals_seller_nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header"
android:fitsSystemWindows="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:menu="#menu/seller_menu"/>
Referencing the TextView in the activity:
docref = FirebaseFirestore.getInstance()
docref.collection("Users").whereEqualTo("uid", userid).get()
.addOnSuccessListener { value->
if (value != null ) {
for (document in value!!) {
val user_name = document.getString("name")!!
val user_surname = document.getString("surname")!!
if(textView15 != null || textView40 != null){
menu_name = findViewById(R.id.textView15)!!
menu_surname = findViewById(R.id.textView40)!!
menu_name.setText("$user_name ")
menu_surname.setText(user_surname)
}
}
} else {
Log.d("Firestore_error", "No Data")
}
}
Do I need a separate navigation header and TextView for each activity?
Edit
Testing this further on API 22, this issue doesnt present itself. Any suggestions?
Instead of calling the findViewById on the activity view you should call it on the header view like so:
docref.collection("Users").whereEqualTo("uid", userid).get()
.addOnSuccessListener { value->
if (value != null ) {
for (document in value!!) {
val user_name = document.getString("name")!!
val user_surname = document.getString("surname")!!
// This gets the first header that is attached to the
// navigation view
val header = mydeals_seller_nav_view.getHeaderView(0)
menu_name = header.findViewById(R.id.textView15)!!
menu_surname = header.findViewById(R.id.textView40)!!
menu_name.setText("$user_name ")
menu_surname.setText(user_surname)
}
}
} else {
Log.d("Firestore_error", "No Data")
}
}
Hope these fixies your issue
menu_name = findViewById(R.id.textView15)!!
menu_surname = findViewById(R.id.textView40)!!
menu_name.setText("$user_name ")
menu_surname.setText(user_surname)
Replace those lines with these:
val headerView = mydeals_seller_nav_view.getHeaderView(0)
val menu_name = headerView.textView15
val menu_surname = headerView.textView40
menu_name.setText("$user_name ")
menu_surname.setText(user_surname)
Please try this...
You have to store that values in prefernces and set preferences values to textview or initialize firbase.instance in onResume() method.
After lots of trial and error its seems like the error was a Firestore query issue. based on my query above i was using a loop where userid id matched the authenticated user. for some reason when moving between activities it resulted in a null pointer. i have no idea why but changing the query above to a single read as below fixed the issue:
docref = FirebaseFirestore.getInstance()
docref.collection("Users").document(userid).get()
.addOnSuccessListener { value->
if (value != null ) {
val user_name = value.getString("name")!!
val user_surname = value.getString("surname")!!
if(textView15 != null || textView40 != null){
menu_name = findViewById(R.id.textView15)!!
menu_surname = findViewById(R.id.textView40)!!
menu_name.setText("$user_name ")
menu_surname.setText(user_surname)
}
} else {
Log.d("Firestore_error", "No Data")
}
}
Just like that, no more NullPointerException. it would be great if a Firestore expert could explain why this was happening.
Related
I am working on one project where I need to display Image Slider with use of ViewPager.
I had done all code and working very fine but now I want to add some animation to my dots indicator as display in this Image.
Here is my code which I write to make indicator.
private fun initLauncherScreen() {
landingScreens = arrayListOf()
landingScreens.add(
LauncherData(
R.drawable.ic_launch_screen,
getString(R.string.get_latest_trends),
getString(R.string.loram)
)
)
landingScreens.add(
LauncherData(
R.drawable.ic_launch_screen,
getString(R.string.get_latest_trends),
getString(R.string.loram)
)
)
landingScreens.add(
LauncherData(
R.drawable.ic_launch_screen,
getString(R.string.get_latest_trends),
getString(R.string.loram)
)
)
landingScreens.add(
LauncherData(
R.drawable.ic_launch_screen,
getString(R.string.get_latest_trends),
getString(R.string.loram)
)
)
val launcherPagerAdapter = LauncherPagerAdapter(this, landingScreens)
binding.launcherPager.adapter = launcherPagerAdapter
setupIndicatorDots(0)
binding.launcherPager.addOnPageChangeListener(object : OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
setupIndicatorDots(position)
}
override fun onPageScrollStateChanged(state: Int) {}
})
}
private fun setupIndicatorDots(position: Int) {
indicators = arrayOfNulls(landingScreens.size)
indicatorLayout = binding.indicatorLayout
indicatorLayout.removeAllViews()
for (i in indicators.indices) {
indicators[i] = TextView(this)
indicators[i]?.setPadding(10, 10, 10, 10)
indicators[i]!!.text = Html.fromHtml("●")
indicators[i]!!.textSize = 18f
indicators[i]!!.setTextColor(ContextCompat.getColor(this, android.R.color.darker_gray))
indicatorLayout.addView(indicators[i])
}
indicators[position]!!.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary))
}
In My Layout Design I have pager like below:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.viewpager.widget.ViewPager
android:id="#+id/launcherPager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/indicatorLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="#dimen/_30sdp"
android:layout_marginVertical="#dimen/_5sdp"
android:gravity="center|center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/launcherPager" /></androidx.constraintlayout.widget.ConstraintLayout>
I need to do animation on scrolling exactly like the image.
Any answer from your side will make me helpful.
Thanks in advance !!
Failed to add data into PieEntry. All the dependencies and repositories are added correctly. It can run, but the output is not as same as what I code in. I have no idea about how to solve it.
Main Activity:
private void ShowPieChart() {
ArrayList<PieEntry> pieEntries = new ArrayList<>();
String label = "type";
//initializing data
Map<String, Integer> typeAmountMap = new HashMap<>();
typeAmountMap.put("Toys",200);
typeAmountMap.put("Snacks",230);
typeAmountMap.put("Clothes",100);
typeAmountMap.put("Stationary",500);
typeAmountMap.put("Phone",50);
//initializing colors for the entries
ArrayList<Integer> colors = new ArrayList<>();
colors.add(Color.parseColor("#304567"));
colors.add(Color.parseColor("#309967"));
colors.add(Color.parseColor("#476567"));
colors.add(Color.parseColor("#890567"));
colors.add(Color.parseColor("#a35567"));
colors.add(Color.parseColor("#ff5f67"));
colors.add(Color.parseColor("#3ca567"));
//input data and fit data into pie chart entry
for(String type: typeAmountMap.keySet()){
pieEntries.add(new PieEntry(typeAmountMap.get(type).floatValue(), type));
}
PieDataSet pieDataSet = new PieDataSet(pieEntries,label);
pieDataSet.setValueTextSize(12f);
pieDataSet.setColors(colors);
PieData pieData = new PieData(pieDataSet);
pieData.setDrawValues(true);
pieChart.setData(pieData);
pieChart.invalidate();
pieChart.setUsePercentValues(true);
pieChart.getDescription().setEnabled(false);
pieChart.setRotationEnabled(true);
pieChart.setDragDecelerationFrictionCoef(0.9f);
pieChart.setRotationAngle(0);
pieChart.setHighlightPerTapEnabled(true);
pieChart.animateY(1400, Easing.EasingOption.EaseInOutQuad);
pieChart.setHoleColor(Color.parseColor("#000000"));
}
XML:
<com.github.mikephil.charting.charts.PieChart
android:id="#+id/pieChart"
android:layout_above="#+id/bottom_navi"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="160dp"
android:layout_marginLeft="160dp"
android:layout_marginTop="287dp"
android:layout_marginEnd="144dp"
android:layout_marginRight="144dp"
android:layout_marginBottom="391dp" />
I'm trying to make a program which will display color that you choose. So you would slide on picture with color shades and application would display you current color. Under that there is text view that will display RGB value of current color. But when I tried to write code for color picker I get this error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.leds/com.example.leds.MainActivity}:
java.lang.NullPointerException: color_picker must not be null
I tried everything but i can't fix it.
My kotlin code:
class MainActivity : AppCompatActivity() {
private lateinit var bitmap:Bitmap
#SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
color_picker.isDrawingCacheEnabled = true
color_picker.buildDrawingCache(true)
val wheel = findViewById<ImageView>(R.id.color_picker)
wheel.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_MOVE) {
bitmap = color_picker.drawingCache
val pixel = bitmap.getPixel(event.x.toInt(), event.y.toInt())
val r = Color.red(pixel)
val g = Color.green(pixel)
val b = Color.blue(pixel)
selected_color_view.setBackgroundColor(Color.rgb(r,g,b))
color_value.text = "RGB: $r, $g, $b"
}
true}
And my xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/color_picker"
android:layout_width="350dp"
android:layout_height="450dp"
android:src="#drawable/colour_wheel"/>
<View
android:id="#+id/selected_color_view"
android:layout_width="100dp"
android:layout_height="100dp" />
<TextView
android:id="#+id/color_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RGB:"
android:textColor="#000"
android:textSize="18sp"/>
It's because you did not initialize variable color_picker before using it
color_picker.isDrawingCacheEnabled = true
color_picker.buildDrawingCache(true)
You have to initialize it like you did in val wheel = findViewById<ImageView>(R.id.color_picker) and then you can modify it like
wheel.isDrawingCacheEnabled = true
#EDIT You have to initialize variable wheel first, then you can call it's properties.
val wheel = findViewById<ImageView>(R.id.color_picker)
wheel.isDrawingCacheEnabled = true
wheel.buildDrawingCache(true)
My code:
Added data in array adapter but last data only comming how to add all the data in spinner using arrayadapter
while (rs.next()) {
int_EMP_ID = rs.getInt("EmpID");
str_EMP_Name = rs.getString("EmployeeName");
int User_ID_List[] = {int_EMP_ID};
String User_name_List[] = {str_EMP_Name};
for (int i=0;i<=10;i++) {
// Step 2: Create and fill an ArrayAdapter with a bunch of "State" objects
ArrayAdapter<Employee> spinnerArrayAdapter = new ArrayAdapter<Employee>(this, android.R.layout.simple_spinner_item, new Employee[]{
new Employee(User_ID_List[i], User_name_List[i]),
new Employee(User_ID_List[i], User_name_List[i])
});
}
Blockquote
<string-array name="array_name">
<item>Array Item One</item>
<item>Array Item Two</item>
<item>Array Item Three</item>
</string-array>
in your layout file.
<Spinner
android:id="#+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:entries="#array/array_name"
/>
Finally got answer
List<Employee> DVDList = new ArrayList<Employee>();
while (rs.next()) {
int_EMP_ID = rs.getInt("EmpID");
str_EMP_Name = rs.getString("EmployeeName");
int i = rs.getInt("EmpID");
String s = rs.getString("EmployeeName");
Employee context = new Employee(int_EMP_ID, str_EMP_Name);
context.setEMPId(i);
context.setEmpName(s);
DVDList.add(context);
}
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, DVDList);
spinner.setAdapter(adapter);
}
I am developing a recycler view with Kotlin. Let's look at my code, when I click on the orderProduct button, the orderRecyclerview is visible and on the contrary, when I click again, the visible is gone. But sometimes when I click on it, the recycler view is shown and sometimes it is not shown.
So how can I do this anytime? How can I solve this bug?
orderProduct.setOnClickListener{
orderProduct.setCompoundDrawablesWithIntrinsicBounds(0, 0, if (!isClicked) R.drawable.btn_down else R.drawable.btn_up, 0)
if (isClicked) {
var r = Runnable {
try {
orderRecyclerview.visibility=View.VISIBLE
paymentList= paymentDb?.paymentDao()?.getAll()!!
mAdapter = PaymentRecylcerViewAdapter(this, paymentList)
mAdapter.notifyDataSetChanged()
orderRecyclerview.adapter = mAdapter
orderRecyclerview.layoutManager = LinearLayoutManager(this)
orderRecyclerview.setHasFixedSize(false)
}catch (e: Exception) {
}
}
val thread = Thread(r)
thread.start()
}else {
orderRecyclerview.visibility=View.GONE
}
isClicked = !isClicked
}
Firstly, you can move this code above the onclickListner.
paymentList= paymentDb?.paymentDao()?.getAll()!!
mAdapter = PaymentRecylcerViewAdapter(this, paymentList)
mAdapter.notifyDataSetChanged()
orderRecyclerview.adapter = mAdapter
orderRecyclerview.layoutManager = LinearLayoutManager(this)
orderRecyclerview.setHasFixedSize(false)
Then inside the onClickListner handle visibility of orderRecyclerview.
For better user experience, You can also add animation in this.
Hope, it will help.
add Dependecy
compile 'net.cachapa.expandablelayout:expandablelayout:2.9.2'
<net.cachapa.expandablelayout.ExpandableLayout
android:id="#+id/expandable_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:el_duration="1000"
app:el_expanded="true"
app:el_parallax="0.5">
<RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Fixed height" />
To trigger the animation, simply grab a reference to the ExpandableLayout from your Java code and and call either of expand(), collapse() or toggle().