I am a newbie to Android and was just trying to implement the fragments by referring the online tutorial.
I am getting an error on the first line of Fragment.kt. I followed all steps perfectly as shown and even tried to search for error on google but nothing seems to be working for me.The error I am getting is as follows.
12-23 19:15:53.369 11656-11656/com.example.mandar.testapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mandar.testapp, PID: 11656
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mandar.testapp/com.example.mandar.testapp.MainActivity}: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2687)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2753)
at android.app.ActivityThread.access$1100(ActivityThread.java:186)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:238)
at android.app.ActivityThread.main(ActivityThread.java:6016)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:937)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:798)
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
at com.example.mandar.testapp.BlankFragment.onCreateView(BlankFragment.kt:0)
at android.app.Fragment.performCreateView(Fragment.java:2236)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:986)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1161)
at android.app.BackStackRecord.run(BackStackRecord.java:800)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1575)
at android.app.FragmentController.execPendingActions(FragmentController.java:325)
at android.app.Activity.performStart(Activity.java:6481)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2650)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2753)
at android.app.ActivityThread.access$1100(ActivityThread.java:186)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:238)
at android.app.ActivityThread.main(ActivityThread.java:6016)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:937)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:798)
MainActivity.kt
package com.example.mandar.testapp
import android.app.Activity
import android.app.Fragment
import android.os.Bundle
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var manager = fragmentManager
var fragment : Fragment? = manager.findFragmentById(R.id.lll)
if(fragment == null){
fragment = BlankFragment()
manager.beginTransaction().replace(R.id.lll,fragment).commit()
}
}
}
activity_main.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"
tools:context="com.example.mandar.testapp.MainActivity">
<FrameLayout
android:id="#+id/lll"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
BlankFragment.kt
package com.example.mandar.testapp
import android.os.Bundle
import android.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
/**
* A simple [Fragment] subclass.
* Use the [BlankFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class BlankFragment : Fragment() {
// TODO: Rename and change types of parameters
private var mParam1: String? = null
private var mParam2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (arguments != null) {
mParam1 = arguments.getString(ARG_PARAM1)
mParam2 = arguments.getString(ARG_PARAM2)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false)
}
companion object {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private val ARG_PARAM1 = "param1"
private val ARG_PARAM2 = "param2"
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
fun newInstance(param1: String, param2: String): BlankFragment {
val fragment = BlankFragment()
val args = Bundle()
args.putString(ARG_PARAM1, param1)
args.putString(ARG_PARAM2, param2)
fragment.arguments = args
return fragment
}
}
}// Required empty public constructor
and fragment_blank.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mandar.testapp.BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
Any Suggestion why this simple code is not working?
Here I am replacing FrameLayout lll with fragment.
The error says: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState. Then savedInstanceState can be null and so you have to add ? after Bundle in your fragment.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false)
}
Please use AppCompatActivity instead of Activity and import import android.support.v4.app.Fragment instead of import android.app.Fragment
for BlankFragment fragment and replace fragmentManager with supportFragmentManager it works perfectly.
Here is your modified code
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var manager = supportFragmentManager
var fragment : Fragment? = manager.findFragmentById(R.id.lll)
if(fragment == null){
fragment = BlankFragment()
manager.beginTransaction().replace(R.id.lll,fragment).commit()
}
}
}
and fragment
import android.os.Bundle
import android.support.annotation.Nullable
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
class BlankFragment : Fragment() {
// TODO: Rename and change types of parameters
private var mParam1: String? = null
private var mParam2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (arguments != null) {
mParam1 = arguments.getString(ARG_PARAM1)
mParam2 = arguments.getString(ARG_PARAM2)
}
}
override fun onCreateView(inflater: LayoutInflater?, #Nullable container: ViewGroup?, #Nullable savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater?.inflate(R.layout.fragment_blank, container, false)
}
companion object {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private val ARG_PARAM1 = "param1"
private val ARG_PARAM2 = "param2"
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
fun newInstance(param1: String, param2: String): BlankFragment {
val fragment = BlankFragment()
val args = Bundle()
args.putString(ARG_PARAM1, param1)
args.putString(ARG_PARAM2, param2)
fragment.arguments = args
return fragment
}
}
}
Related
I got this error while using the replace function to change the frame of the main Activity with the fragment that I created it shows type mismatch required fragment found DashboardFragmentComapnion
package com.shivanshu.bookhub
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.widget.FrameLayout
import android.widget.Toast
import android.widget.Toolbar
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView
class MainActivity : AppCompatActivity() {
lateinit var drawerLayout: DrawerLayout
lateinit var coordinatorLayout: CoordinatorLayout
lateinit var toolbar: androidx.appcompat.widget.Toolbar
lateinit var frameLayout: FrameLayout
lateinit var navigationView: NavigationView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
drawerLayout = findViewById(R.id.drawerLayout)
coordinatorLayout = findViewById(R.id.coordinatorLayout)
toolbar = findViewById(R.id.toolbar)
frameLayout = findViewById(R.id.frameLayout)
navigationView = findViewById(R.id.navigationView)
setUpToolbar()
val actionBarDrawerToggle = ActionBarDrawerToggle(
this#MainActivity,
drawerLayout,
R.string.open_drawer,
R.string.close_drawer
)
drawerLayout.addDrawerListener(actionBarDrawerToggle)
actionBarDrawerToggle.syncState()
navigationView.setNavigationItemSelectedListener {
when(it.itemId){
R.id.dashboard -> {
supportFragmentManager.beginTransaction().
replace(R.id.frameLayout, DashboardFragment).commit()
}
R.id.profile ->{
Toast.makeText(this#MainActivity,"Profile Clicked",Toast.LENGTH_LONG)
}
R.id.about_app -> {
Toast.makeText(this#MainActivity,"About Section Clicked",Toast.LENGTH_LONG)
}
R.id.favourites -> {
Toast.makeText(this#MainActivity,"Favourites Clicked",Toast.LENGTH_LONG)
}
}
return#setNavigationItemSelectedListener true
}
}
fun setUpToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.title = "Toolbar Title"
supportActionBar?.setHomeButtonEnabled(true)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if(id == android.R.id.home){
drawerLayout.openDrawer(GravityCompat.START )
}
return super.onOptionsItemSelected(item)
}
}
The fragment file:
package com.shivanshu.bookhub
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [DashboardFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class DashboardFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_dashboard2, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment DashboardFragment.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic fun newInstance(param1: String, param2: String) =
DashboardFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
I implement the NavigationDrawer having various menu items when I click on the dashboard menu item it will open the dashboard fragment I created
You should pass an instance of DashboardFragment to replace function.
val dashboardFragmentInctance = DashboardFragment.newInstance("param","param")
supportFragmentManager.beginTransaction().
replace(R.id.frameLayout, dashboardFragmentInctance).commit()
Can someone help me on how to transfer data from one recyclerview fragment to another recyclerview fragment?
This is my newly created CartRecyclerAdapter.kt for my cart recyclerview from a fragment. The main idea of SubmitItem() is to accept the selected item in the Itemrecyclerview.
package com.example.karawapplication
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.example.karawapplication.models.ItemPost
import kotlinx.android.synthetic.main.layout_item_cart_list.view.*
import kotlinx.android.synthetic.main.layout_item_list_item.view.*
class CartRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var Items : List<ItemPost> = emptyList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ItemRecyclerAdapter.ItemViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.layout_item_cart_list, parent, false)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(holder)
{
is ItemRecyclerAdapter.ItemViewHolder ->
{
holder.bind(Items.get(position))
}
}
}
override fun getItemCount(): Int {
return Items.size
}
fun SubmitItem(Item : ItemPost)
{
Items.toMutableList().add(Item)
}
class ItemViewHolder constructor(
Itemview : View
): RecyclerView.ViewHolder(Itemview)
{
val ItemImage : ImageView = Itemview.Item_image_cart
val ItemTitle : TextView = Itemview.Item_title_cart
val ItemCategory: TextView = Itemview.Item_category_cart
val ItemPrice : TextView = Itemview.Item_price_cart
fun bind (itempost : ItemPost)
{
ItemTitle.setText(itempost.Itemtitle)
ItemCategory.setText(itempost.ItemCategory)
ItemPrice.setText(itempost.ItemPrice)
val requestOptions = RequestOptions()
.placeholder(R.drawable.ic_baseline_brush_24)
.error(R.drawable.ic_baseline_brush_24)
Glide.with(itemView.getContext())
.applyDefaultRequestOptions(requestOptions)
.load(itempost.image)
.into(ItemImage)
}
}
}
This is where I use the SubmitItem() in my ItemRecyclerAdapter.kt which contains items of my shop app and displayed from another fragment. CartAdapter is the adapter of the cart that I recently created in order to access the function SubmitItem().
ItemButton.setOnClickListener()
{
Toast.makeText(itemView.context, "${itempost.image}, ${itempost.Itemtitle}, ${itempost.ItemPrice}", Toast.LENGTH_SHORT).show()
CartAdapter.SubmitItem(ItemPost(itempost.image,itempost.Itemtitle,itempost.ItemCategory,itempost.ItemPrice))
}
This is my code for my fragments
ShopFragment.kt contains the recyclerview of my items.
package com.example.karawapplication.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.android.volley.Request
import com.android.volley.VolleyError
import com.android.volley.toolbox.JsonArrayRequest
import com.android.volley.toolbox.Volley
import com.example.karawapplication.ItemRecyclerAdapter
import com.example.karawapplication.R
import com.example.karawapplication.models.ItemPost
import kotlinx.android.synthetic.main.fragment_shop.*
import org.json.JSONException
import org.json.JSONObject
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [Shop.newInstance] factory method to
* create an instance of this fragment.
*/
class Shop : Fragment(){
// TODO: Rename and change types of parameters
private lateinit var ItemAdapter : ItemRecyclerAdapter
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_shop, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRecyclerView()
addDataSet()
}
// CUSTOM FUNCTIONS
private fun addDataSet()
{
createDataset {
list -> ItemAdapter.SubmitList(list)
}
}
private fun initRecyclerView()
{
ShopRecycleView.layoutManager = LinearLayoutManager(activity)
ItemAdapter = ItemRecyclerAdapter()
ShopRecycleView.adapter = ItemAdapter
//Toast.makeText(context, "Recycler Trigger", Toast.LENGTH_SHORT).show()
}
// https://tutorials.eu/json-parsing-and-how-to-use-gson-in-android/
// Generates the data for the recycleview
fun createDataset(onSuccess: (List<ItemPost>) -> Unit){
val url = "http://api.karawcraftventure.com/item"
// LIST DATA VARIABLE FOR RECYCLEVIEW
val list = ArrayList<ItemPost>()
// VOLLEY API REQUEST
val Queue = Volley.newRequestQueue(activity)
val jsonObject = JsonArrayRequest(
Request.Method.GET,url,null,
{response ->
try
{
for (i in 0 until response.length())
{
val item : JSONObject = response.getJSONObject(i)
val API_Image : String = item.getString("product_url_image")
val API_ItemName : String = item.getString("product_name")
val API_Price : String = item.getString("product_price")
val API_Category : String = item.getString("product_category")
// Toast Notif if data is extracted or not
//Toast.makeText(context, "$API_ItemName - $API_Price - $API_Category", Toast.LENGTH_SHORT).show()
list.add(ItemPost(API_Image, API_ItemName, API_Category, API_Price))
}
onSuccess(list)
}
catch (e: JSONException)
{
e.printStackTrace()
}
},
{ error: VolleyError? -> Toast.makeText(context, error?.message.toString(), Toast.LENGTH_SHORT).show()
}
)
Queue.add(jsonObject)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Shop.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
Shop().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
Cart.kt fragment on the other hand, contains my shopping cart.
package com.example.karawapplication.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.karawapplication.CartRecyclerAdapter
import com.example.karawapplication.ItemRecyclerAdapter
import com.example.karawapplication.R
import kotlinx.android.synthetic.main.fragment_cart.*
import kotlinx.android.synthetic.main.fragment_shop.*
import kotlinx.android.synthetic.main.fragment_shop.ShopRecycleView
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [Cart.newInstance] factory method to
* create an instance of this fragment.
*/
class Cart : Fragment() {
// TODO: Rename and change types of parameters
private lateinit var ItemAdapter : CartRecyclerAdapter
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRecyclerView()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_cart, container, false)
}
private fun initRecyclerView()
{
Cart_RecyclerView.layoutManager = LinearLayoutManager(activity)
ItemAdapter = CartRecyclerAdapter()
Cart_RecyclerView.adapter = ItemAdapter
//Toast.makeText(context, "Recycler Trigger", Toast.LENGTH_SHORT).show()
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Cart.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
Cart().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
The code has no errors, but it does not show any output in my cart recyclerview fragment.
(I'm going to follow the "starts with a lowercase letter" convention for variables and functions here, because I'm tired and it's less confusing)
Your submitItem function just creates a new copy of items (items.toMutableList()) and adds to that. Then it's immediately discarded when you exit the function.
All your adapter code that handles your data (getItemCount, onBindViewHolder) references items, so you need to update that instead, and let the adapter know it's changed:
fun submitItem(item: ItemPost) {
// plus creates a copy, but adds the new item without making the result mutable
items = items.plus(item)
// we also need to tell the adapter that the data has changed, so it can
// update - there are more efficient calls (you'll probably get a lint
// warning telling you to use one) but this is the simplest
notifyDataSetChanged()
}
This is just making your adapter update correctly - I'm assuming you've got your communication between the two fragments set up properly (communicating through the parent activity, passing one fragment's adapter into the other, using a view model). Have a read of this if you need to: Communicating with fragments
Here is the piece of code that I have been trying.
The adapter code is below.
Made an array list for storing the data, and want to display it in the fragment using grid view. The app is running but its not showing the grid layout.
import android.os.strictmode.WebViewMethodCalledOnWrongThreadViolation
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import com.shyptsolution.nitrr.R
class GalleryAdapter(gallerylist:ArrayList<GalleryDataModel>):BaseAdapter() {
var galleryList=gallerylist
var image:ImageView?=null
override fun getCount(): Int {
return galleryList.size
}
override fun getItem(position: Int): Any {
return galleryList[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var inflator=LayoutInflater.from(parent?.context).inflate(R.layout.gallery_ticket,null)
image=inflator.findViewById(R.id.gallery)
image?.setImageResource(galleryList[position].image)
return inflator
}
}
The code for the fragment is given below
package com.shyptsolution.nitrr.gallery
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.GridView
import com.shyptsolution.nitrr.R
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [Gallery.newInstance] factory method to
* create an instance of this fragment.
*/
class Gallery : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
lateinit var adapter:GalleryAdapter
var gallerygrid=activity?.findViewById<GridView>(R.id.galllerygrid)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
adapter= GalleryAdapter(GalleryData.galleryphoto)
gallerygrid?.adapter=adapter
return inflater.inflate(R.layout.fragment_gallery, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Gallery.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
Gallery().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
How can I do it, I have done recycler view in the fragment but couldn't figure out the problem here.
Here is the list of changes that I have made and now its working fine.
package com.shyptsolution.nitrr.gallery
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.GridLayout
import android.widget.GridView
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.GridLayoutManager
import com.shyptsolution.nitrr.R
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [Gallery.newInstance] factory method to
* create an instance of this fragment.
*/
class Gallery : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
var listofphoto=GalleryData.galleryphoto
lateinit var adapter:GalleryAdapter
var gallerygrid=activity?.findViewById<GridView>(R.id.galllerygrid)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
// adapter=GalleryAdapter(listofphoto)
// var galleryview=activity?.findViewById<GridView>(R.id.galllerygrid)
// galleryview?.adapter=adapter
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
// adapter= GalleryAdapter(GalleryData.galleryphoto)
// gallerygrid?.adapter=adapter
var view:View=inflater.inflate(R.layout.fragment_gallery, container, false)
gallerygrid=view.findViewById(R.id.galllerygrid)
adapter= GalleryAdapter(listofphoto)
gallerygrid?.adapter=adapter
return view
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Gallery.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
Gallery().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
Added the Gallery adapter and then set the grid adapter. Its working fine.
I'm trying to set up recycler view to work with the fragment I created, and in MainActivity after "val recyclerV = findViewById(R.id.plantsRecyclerView)" I'm getting " java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.NullPointerException: findViewById<RecyclerVie…(R.id.plantsRecyclerView) must not be null" even though the recycler with that Id exists, any ideas how can I fix that?
Thanks in advance!
(code:
Main Activity:
private var numPlants = 4
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//there is some parts that I'm not posting because they are not relevant (at least I think so <it's mainly code that creates notifications>)
val recyclerV = findViewById<RecyclerView>(R.id.plantsRecyclerView)
recyclerV.layoutManager = LinearLayoutManager(this)
recyclerV.adapter = MyRecyclerViewAdapter(this, numPlants)
}
}
MyRecyclerViewAdapter:
package com.example.myapplication
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
class MyRecyclerViewAdapter(private val context: Context, private val numPlants: Int) :
RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.card_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(position)
}
override fun getItemCount() = numPlants
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
fun bind(position: Int){
// not implemented yet
}
}
}
fragment main (the fragment that recycler view inside of it):
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/darker_green"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/plantsRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainFragment (I haven't changed anything here after creation, and I suppose that is the problem):
package com.example.myapplication
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [MainFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class MainFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment MainFragment.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
MainFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
Because your RecyclerView is in MainFragment. Not in MainActivity. Make your RecyclerView in MainFragment.
I'm getting a IllegalStateException. Believe this is because my ProcessFragment.kt cannot identify id "title" for a TextView under fragment_process.xml.
How can I edit my code such that ProcessFragment.kt does not cause java.lang.IllegalStateException?
Thank you very much.
This is where the error occurs:
title.text = initProcess()
}
private fun initProcess(): String {
val python = Python.getInstance()
val pythonFile = python.getModule("ProcessFile")
return pythonFile.callAttr("Function1").toString()
}
ProcessFragment.kt
class ProcessFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
title.text = initProcess()
}
private fun initProcess(): String {
val python = Python.getInstance()
val pythonFile = python.getModule("ProcessFile")
return pythonFile.callAttr("Function1").toString()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_process, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment ProcessFragment.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
ProcessFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
fragment_process.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"
tools:context="view.ProcessFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>