I noticed that after creating a fragment an element is expected. In Java, all that was needed was getActivity() but it seems more difficult in Kotlin. < and > in mTwoPane = <FragmentActivity>(activity).findViewById(R.id.master_container) != null become red underlined and return this error:
Expecting an element
class MyFragment() : Fragment() {
private var mAdapter: MyListAdapter? = null
internal lateinit var mRecyclerView: RecyclerView
var mTwoPane: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.md, container, false)
mTwoPane = <FragmentActivity>(activity).findViewById(R.id.master_container) != null
mRecyclerView = view.findViewById(R.id.recyclerView_list)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = LinearLayoutManager(this.activity)
mRecyclerView.addItemDecoration(DividerItemDecoration(Objects.requireNonNull<Context>(context), LinearLayout.VERTICAL))
val myList = ArrayList<Product>()
val items = resources.getStringArray(R.array.product_names)
val itemDescriptions = resources.getStringArray(R.array.product_descriptions)
for (n in items.indices) {
val product = Product(items[n], itemDescriptions[n])
myList.add(product)
}
mAdapter = MyListAdapter(activity, myList, mTwoPane)
mRecyclerView.adapter = mAdapter
return view
}
}
try this
mTwoPane = (activity as FragmentActivity).findViewById<View>(R.id.master_container) != null
Related
I use viewPager2 in my project the parent is HomeFragment and one of child Fragment is Fragmentone . I cached the root View of HomeFragment so next time I goto HomeFragment I can reuse it . ComposeView is add to Fragmentone. it can not show when I goto HomeFragment again.
class HomeFragment : BaseTrackFragment() {
lateinit var mTabs: TabLayout
private lateinit var mFragmentPager: ViewPager2
private var pageAdapter:HomePageAdapter? = null
val mFragmentList = SparseArray<Fragment>()
private var mView: View? = null
override fun initShareTrackParams(shareTrackParamsCtx: ShareTrackParamsCtx) {
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
if (mView!=null){
(mView?.parent as? ViewGroup)?.removeView(mView)
return mView as View
}
val root = inflater.inflate(R.layout.fragment_home, container, false)
mView = root
mTabs = root.findViewById(R.id.tab_header)
mFragmentPager = root.findViewById(R.id.fragment_pager)
try {
setupViewPager()
} catch (e: Exception) {
}
return root
}
private fun setupViewPager() {
pageAdapter = HomePageAdapter(mFragmentList,this)
mFragmentPager?.adapter = pageAdapter
mFragmentPager.isSaveEnabled = false
mTabs.layoutParams = mTabs.layoutParams.apply {
width = 2 * 120
}
TabLayoutMediator(mTabs, mFragmentPager) { t, position ->
t.text = if (position==0) "音乐" else "K歌"
}.attach()
mTabs.disableTooltips()
}
private fun TabLayout.disableTooltips() {
for (i in 0 until childCount) {
val c = getChildAt(i)
if (c is ViewGroup) {
for (j in 0 until c.childCount) {
val cc = c.getChildAt(j)
if (cc is TabLayout.TabView) {
// Avoid calling tooltip for L and M devices because long pressing twuice may freeze devices.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
TooltipCompat.setTooltipText(cc, null)
}
}
}
}
}
}
}
class Fragmentone : BaseTrackFragment(){
// TODO: Rename and change types of parameters
override fun initShareTrackParams(shareTrackParamsCtx: ShareTrackParamsCtx) {
}
var listView:ListView?=null
var composeView:ComposeView?=null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fragmentone, container, false).apply {
listView = findViewById<ListView>(R.id.list_view)
composeView = findViewById<ComposeView>(R.id.compose_view).apply {
setContent {
Text(text = "我是测试的。。。。。")
}
}
listView?.adapter = MyAdapter(this.context)
}
}
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 Fragmentone.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
Fragmentone().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
<?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"
tools:context=".ui.home.Fragmentone">
<androidx.compose.ui.platform.ComposeView
android:id="#+id/compose_view"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
i want to know how pass data from one fragment to other using LiveData
i have this code and do somethings that i know but it doesnt work pls help ...
this is my first fragmetn
enter code here
class ItemDetailsfragment : Fragment() {
lateinit var viewmodel: ViewModelPassItem
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.details_items_page, container, false)
val title = arguments?.getString("title")
view.title_details_item.text = title
val price = arguments?.getString("price")
view.price_item_details.text = price
val image = arguments?.getString("image")
Picasso.get().load(image).into(view.image_items_detail)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewmodel = ViewModelProviders.of(activity!!).get(ViewModelPassItem::class.java)
val title: TextView = view.findViewById(R.id.title_details_item)
view.plus_icon_item_details.setOnClickListener {
viewmodel.passdata(title.text.toString())
val myfragment = Cart_Fragment()
}
}
}
and this is second fragment
enter code here
class Cart_Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val viewitem = inflater.inflate(R.layout.cart_fragment, container, false)
val choosebtn: Button = viewitem.findViewById(R.id.choose_titme_and_submit_order_btn)
choosebtn.visibility = View.GONE
val rl_cart = viewitem.findViewById<RecyclerView>(R.id.recycler_view_cart)
rl_cart.visibility = View.GONE
val navbar: BottomNavigationView = activity!!.findViewById(R.id.nav_view_bottom_main)
navbar.visibility = View.GONE
val homeicon: ImageButton = viewitem.home_icon_cart
homeicon.setOnClickListener {
activity?.let {
val intent = Intent(requireContext(), HomeActivity::class.java)
it.startActivity(intent)
}
}
viewitem.start_shopping_in_cart.setOnClickListener {
activity?.let {
val intent = Intent(requireContext(), HomeActivity::class.java)
it.startActivity(intent)
}
}
return viewitem
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val viewmodel = ViewModelProviders.of(activity!!).get(ViewModelPassItem::class.java)
viewmodel.pass.observe(activity!!, Observer {
d("main", "${it.toString()}")
})
}
}
and this is my ViewModel Class
enter code here
class ViewModelPassItem:ViewModel() {
val pass = MutableLiveData<String>()
fun passdata (title : String) {
pass.postValue(title)
}
}
ok
when i click on btn to get string that i pass nothing happend ...
In the Cart Fragment instead of passign activity lifecycleowner pass your fragments lifecycle owner. So instead of :
viewmodel.pass.observe(activity!!, Observer {
Log.d("main", "${it.toString()}")
})
Do this :
viewmodel.pass.observe(this.viewLifecycleOwner, Observer {
Log.d("main", "${it.toString()}")
})
Code using kotlin,
first,this is my error code.
this is my used extends BaseFragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val cacheView = mView == null
if (cacheView) {
mView = inflater.inflate(getFragLayoutResID(), container, false)
initView(mView!!)
}
return mView
}
//When used in an activity
fun addFragment(context: FragmentActivity, fragmentContainer: Int) {
val fragmentManager = context.supportFragmentManager
val ft = fragmentManager.beginTransaction()
ft.replace(fragmentContainer, this, javaClass.simpleName).addToBackStack(javaClass.simpleName)
.commitAllowingStateLoss()
ft.setMaxLifecycle(this, Lifecycle.State.RESUMED)
}
this is my HomeActivity
homeVideoFragment.addFragment(mContext as FragmentActivity, mainFrameLayout.id)
this is my HomeFragment
//HomeFragment
override fun initView(view: View) {//this is my homeFragment
initAdapter()
//init()
}
private var homeVideoAdapter: HomeVideoAdapter? = null
private fun initAdapter() {//this is my init adapter
val homeVideoManager = LinearLayoutManager(mContext, RecyclerView.VERTICAL, false)
homeVideoAdapter = HomeVideoAdapter(mContext!!)
home_video_rv.layoutManager = homeVideoManager
home_video_rv.adapter = homeVideoAdapter
}
private fun init() = runBlocking {
GlobalScope.launch(Dispatchers.Main) {
initAdapter()
//GlobalScope.async(Dispatchers.IO) {
//presenter!!.getVideoClassPost(AllPort.POST_GET_VIDEO_HOME)//network requests
//}.await()
}
}
When the code is run like this, it will report an error: home_video_rv must not be null.
But when I use init(), it works fine.
Although successful, but can not make network requests.
Why is this problem occurring?
Use onViewCreated method
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val cacheView = mView == null
if (cacheView) {
mView = inflater.inflate(getFragLayoutResID(), container, false)
}
return mView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView(view)
}
when I add a fragment to my view, it is not displayed. Only when I click an OptionsButton the fragment becomes visible. But I don't know if the RecyclerView just doesn't show any elements or if the fragment isn't started.
Code from MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
val fragment= ArticleFragment()
var args=Bundle()
args.putInt("id",0)
fragment.arguments=args
supportFragmentManager.beginTransaction().replace(R.id.fragment_area,fragment).addToBackStack(null).commit()
}
Code from ArticleFragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val view= inflater.inflate(R.layout.fragment_article, container, false)
articles=getArticleJson(url)
val recyclerView=view.findViewById<RecyclerView>(R.id.articlesRecyclerView)
recyclerView.setHasFixedSize(true)
val lm = LinearLayoutManager(activity)
recyclerView.layoutManager = lm
val adapter = ArticleAdapter(context = context, articles = articles) {
val intent = Intent(activity, ArticleWebActivity::class.java).apply
{
putExtra("article", Gson().toJson(it))
}
startActivity(intent)
}
recyclerView.adapter = adapter
return view
}
The TextView wont display the text while the value is existed. This operation is called within onViewCreated inside fragment. In the same case, the OnClickListener is also not working.
I have searched for the similar issue but have not found the exact same case. Did I miss something? Thank you for any help.
import kotlinx.android.synthetic.main.fragment_login.*
---
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_login, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val isLogin = activity?.let { PrefHelper.getBoolean(it, PrefHelper.IS_LOGIN, false) }
if (isLogin != null && isLogin) {
onSignedIn()
} else {
onSignedOut()
}
}
private fun onSignedIn() {
form_login.visibility = View.GONE
user_profile.visibility = View.VISIBLE
var sEmail = ""
var sFullName = ""
var sPhone = ""
if (activity != null) {
PrefHelper.putBoolean(activity!!, PrefHelper.IS_LOGIN, true)
sEmail = PrefHelper.getString(activity!!, PrefHelper.USER_EMAIL, "")
sFullName = PrefHelper.getString(activity!!, PrefHelper.USER_FULL_NAME, "")
val sPhonePrefix = PrefHelper.getString(activity!!, PrefHelper.USER_PHONE_PREFIX, "")
val sPhoneSuffix = PrefHelper.getString(activity!!, PrefHelper.USER_PHONE_SUFFIX, "")
sPhone = "$sPhonePrefix $sPhoneSuffix"
}
user_email.text = sEmail
user_full_name.text = sFullName
user_phone.text = sPhone
logout.setOnClickListener { onSignedOut() }
}
the UI
breakpoint