I have been working on an app where were people can watch videos like tik tok. At first I made it with recyclerview and later on I realized that I should use Vertical Viewpager. Then I used Viewpager2 but I faced some problems so I replaced it with viewpager1. But still it is not working. I am doing this in my fragment. I want to play videos from firebase in Vertical viewpager using videoview.
In Viewpager_Adapter u can see that I have called one more layout there which is viewer_page but when I run my app I don't get that layout in my fragment
ViewpagerAdapter
class ViewpagerAdapter(var context: Context) : PagerAdapter() {
lateinit var inflater: LayoutInflater
var contentDTOs: ArrayList<ContentDTOs> = arrayListOf()
var contentUidList: ArrayList<String> = arrayListOf()
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object` as ConstraintLayout
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object`as ConstraintLayout)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
inflater = context.getSystemService(container.context.toString())as LayoutInflater
val view =inflater.inflate(R.layout.viewer_page,container,false)
val exo : View? = view?.findViewById(R.id.videoviews)
val path = Uri.parse(contentDTOs[position].videourl)
val views = view.findViewById<VideoView>(R.id.videoviews)
views.setVideoURI(path)
views.requestFocus()
views.setOnPreparedListener {
views.start()
}
container.addView(view)
return view
}
override fun getCount(): Int {
return contentDTOs.size
}
}
Watch_video_fragment
#SuppressLint("ResourceAsColor")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val fragmentview = inflater.inflate(R.layout.fragment_watch_video, container, false)
fragmentview.videofragment?.setOnClickListener {
var fragment = Watch_video()
activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.frag, fragment)
?.commit()
}
fragmentview.memefragment?.setOnClickListener {
var fragment = DetailViewFragment()
activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.frag, fragment)
?.commit()
}
firestore = FirebaseFirestore.getInstance()
uid = FirebaseAuth.getInstance().currentUser?.uid
fragmentview.videofragment?.setOnClickListener {
var fragment = Watch_video()
activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.frag, fragment)
?.commit()
}
//
fragmentview.vertical_viewpager.adapter = ViewpagerAdapter(requireContext())
fragmentview.vertical_viewpager.setPageTransformer(false
) { page, position ->
page.rotationY = position * -30 // animation style... change as you want..
}
Can u guys plz help me
Related
I'm trying to show images from my Firebase Realtime Database storage. I've done this before with a previous version of my app, but the difference is how I implemented it. My adapter and arraylist class are exactly the same, but instead of using an activity I switched to using fragments.
What I essentially did was copy my old work and make the appropriate changes so I wouldn't run into errors, but unfortunately I ran into some. My images from Firebase are not showing up at all and I'm not sure what is the problem.
Adapter Class
class AbstractAdapter(private val mContext: Context, private val abstractList: ArrayList<Abstract>) : RecyclerView.Adapter<AbstractAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.abstract_image_view, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Glide.with(mContext)
.load(abstractList[position].abstract)
.into(holder.imageView)
}
override fun getItemCount(): Int {
return abstractList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var imageView: ImageView = itemView.findViewById(R.id.abstractImageView)
}
companion object {
private const val Tag = "RecyclerView"
}
}
Data class
class Abstract {
var abstract: String? = null
constructor() {}
constructor(abstract: String?) {
this.abstract = abstract
}
}
Fragment in which images will be shown
class AbstractWallpapers: Fragment(), PurchasesUpdatedListener {
private lateinit var subscribeAbstract: Button
private var billingClient: BillingClient? = null
lateinit var recyclerView: RecyclerView
lateinit var abstractlist: ArrayList<Abstract>
private var recyclerAdapterAbstract: AbstractAdapter? = null
private var myRef3: DatabaseReference? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_abstract_wallpaper, container, false)
recyclerView = requireView().findViewById(R.id.abstract_recyclerView)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView = view.findViewById(R.id.abstract_recyclerView)
val layoutManager = LinearLayoutManager(requireActivity())
recyclerView.layoutManager = layoutManager
recyclerView.setHasFixedSize(true)
myRef3 = FirebaseDatabase.getInstance().reference
abstractlist = ArrayList()
ClearAll()
GetDataFromFirebase()
subscribeAbstract = view.findViewById(R.id.abstract_subscribe_btn)
subscribeAbstract.setOnClickListener {
subscribeAbstract()
}
// Establish connection to billing client
//check subscription status from google play store cache
//to check if item is already Subscribed or subscription is not renewed and cancelled
billingClient = BillingClient.newBuilder(requireActivity()).enablePendingPurchases().setListener(this).build()
billingClient!!.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
val queryPurchase = billingClient!!.queryPurchases(BillingClient.SkuType.SUBS)
val queryPurchases = queryPurchase.purchasesList
if (queryPurchases != null && queryPurchases.size > 0) {
handlePurchases(queryPurchases)
} else {
saveSubscribeValueToPref(false)
}
}
}
override fun onBillingServiceDisconnected() {
Toast.makeText(requireActivity(), "Service Disconnected", Toast.LENGTH_SHORT).show()
}
})
//item subscribed
if (subscribeValueFromPref) {
subscribeAbstract.visibility = View.GONE
} else {
subscribeAbstract.visibility = View.VISIBLE
}
}
// Code related to Firebase
#SuppressLint("NotifyDataSetChanged")
private fun GetDataFromFirebase() {
val query: Query = myRef3!!.child("Abstract")
query.addListenerForSingleValueEvent(object : ValueEventListener {
#SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
for (dataSnapshot: DataSnapshot in snapshot.children) {
val abstract = Abstract()
abstract.abstract = dataSnapshot.child("abstract").value.toString()
abstractlist.add(abstract)
}
recyclerAdapterAbstract = abstractlist.let { AbstractAdapter(requireActivity(), it) }
recyclerView.adapter = recyclerAdapterAbstract
recyclerAdapterAbstract!!.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {}
})
if (recyclerAdapterAbstract != null) recyclerAdapterAbstract!!.notifyDataSetChanged()
}
private fun ClearAll() {
abstractlist.clear()
abstractlist = ArrayList()
}
I fixed my problem. It turns out my rules in Firebase Realtime Database rules for read were set to false instead. My code works perfect. It was only a stupid error on my part.
Im in a fragment1 and i want go to fragment2 if an event occurred in a class called from the fragment1. I have tried a callback of fuction: function in Class call a function in fragment1 to go in fragment but i collect this error:
Process: com.example.ilmiogioco, PID: 7992java.lang.IllegalStateException: Method addObserver must be called on the main thread
at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:317)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:172)
at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:61)
at androidx.navigation.NavBackStackEntry.<init>(NavBackStackEntry.java:88)
at androidx.navigation.NavBackStackEntry.<init>(NavBackStackEntry.java:73)
at androidx.navigation.NavController.navigate(NavController.java:1138)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.NavController.navigate(NavController.java:863)
at androidx.navigation.NavController.navigate(NavController.java:851)
at com.example.ilmiogioco.FullscreenFragmentSolo.follow(FullscreenFragmentSolo.kt:77)
at com.example.ilmiogioco.Solo.SpaceView.update(SpaceView.kt:276)
at com.example.ilmiogioco.Solo.SpaceView.run(SpaceView.kt:120)
at java.lang.Thread.run(Thread.java:919)
EDIT: I have fullscreenfragmentsolo (fragment1) that want in gameoverfragment (fragment2) if the class spaceview called in fullscreenfragmentsolo collect a lost game. The function follow() is called by spaceview for return in fullscreenfragmentsolo (maybe this is the thread error).
class FullscreenFragmentSolo : Fragment() {
private var spaceView: SpaceView? = null
private lateinit var backgroundMusic: MediaPlayer
private lateinit var window: Window
private var binding: FragmentFullscreenSoloBinding? = null
object size{
var x = 0
var y = 0
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
(activity as AppCompatActivity?)!!.supportActionBar!!.hide()
getActivity()?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
val soundEffects = SoundEffects(requireContext())
soundEffects.playSound(SoundEffects.backgroundMusic)
val outMetrics = DisplayMetrics()
getActivity()?.getWindow()?.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
window = activity?.getWindow()!!
window.attributes.width
window.attributes.height
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
val display = activity?.display
display?.getRealMetrics(outMetrics)
} else {
#Suppress("DEPRECATION")
val display = activity?.windowManager?.defaultDisplay
#Suppress("DEPRECATION")
display?.getMetrics(outMetrics)
}
size.y = outMetrics.heightPixels
size.x = outMetrics.widthPixels
backgroundMusic = MediaPlayer.create(requireContext(), R.raw.background_music)
backgroundMusic.isLooping = true
backgroundMusic.start()
val fragmentBinding = FragmentFullscreenSoloBinding.inflate(inflater, container, false)
binding = fragmentBinding
fragmentBinding.root
spaceView = SpaceView(requireContext(), size, this)
return spaceView
}
fun follow(){
findNavController().navigate(R.id.action_fullscreenFragmentSolo_to_gameoverFragment)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.soloFragment = this
}
override fun onResume() {
super.onResume()
spaceView?.resume()
}
fun stopFunction() {
spaceView?.stop()
}
override fun onPause() {
super.onPause()
backgroundMusic.release()
spaceView?.pause()
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
GameoverFragment:
open class GameoverFragment : Fragment() {
private var binding: GameoverFragmentBinding? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val fragmentBinding = GameoverFragmentBinding.inflate(inflater, container, false)
binding = fragmentBinding
return fragmentBinding.root
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.gameoverFragment = this
}
fun Menu(){
findNavController().navigate(R.id.action_gameoverFragment_to_startFragment)
}
> override fun onDestroyView() {
> super.onDestroyView()
> binding = null }
Can you help me?
This exception is due to your code calling (through navigation) the LifecycleRegistry.addObserver from a thread other than the Main thread. You have to ensure that you call the navigation from the main thread.
Change to this in the follow() function
import android.os.Handler
import android.os.Looper
// ...
fun follow() {
Handler(Looper.getMainLooper()).post {
findNavController().navigate(R.id.action_fullscreenFragmentSolo_to_gameoverFragment)
}
}
I am very new to taking an android application and for a project I need a BottomNavigati but I cannot get my data that comes from the beginning of the session to pass to the main fragment
Activity:
val bundle1 = Bundle()
bundle1.putString("User",User)
bundle1.putString("Correo",Correo)
bundle1.putString("Region",Region)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController: NavController = navHostFragment.navController
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
navHostFragment.arguments = bundle1
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
HOMEFRAGMEN:
private lateinit var homeViewModel: HomeViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
val textView: TextView = root.findViewById(R.id.textView4)
return root
}
}
There is no direct access to HomeFragment from MainActivity in your case. BottomNavigation uses nested navigation architecture pattern with nested graphs.
More details here: Passing argument(s) to a nested Navigation architecture component graph
But you can use alternative way to pass data from Activity to Fragment using context.
Step 1 - Describe HomeFragmentData model:
data class HomeFragmentData(
val value: String
)
Step 2 - Describe HomeFragment interface:
interface IHomeFragment {
fun getHomeFragmentData(): HomeFragmentData
}
Step 3 - Implement interface to your Activity:
class MainActivity : AppCompatActivity(), IHomeFragment {
override fun getHomeFragmentData(): HomeFragmentData {
return HomeFragmentData(
value = "Home Fragment data"
)
}
// Rest of your code
}
Step 4 - Call function getHomeFragmentData() from HomeFragment using context:
class HomeFragment : Fragment() {
private var interactionListener: IHomeFragment? = null
override fun onAttach(context: Context) {
super.onAttach(context)
when(context) {
is IHomeFragment -> {
interactionListener = context
}
else -> throw RuntimeException("$context has to implement IHomeFragment")
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment_home, container, false)
val textView: TextView = root.findViewById(R.id.text_home)
interactionListener?.getHomeFragmentData().let {
textView.text = it?.value
}
return root
}
}
I'm having a problem with this SmartToolbar, if I open the app and click on the chat or book icon it opens perfectly and shows the fragments, but if I click on another icon to open another fragment, when I go back to them they don't show more The fragments that should be on the smartToolbar, as shown in the prints below, bug everything! I need to help on this as soon as possible !!!
[Opens normally When I click on another item and go back to it, it no longer opens the SmartToolbar fragmentshere]2
enter image description here
I will send the homeAcitivity code, where is the layout that opens the fragments of the buttonNavigationBar
class HomeActivity : AppCompatActivity() {
var MY_ACCOUNT = 1
var LIBRARY = 2
var HOME = 3
var CHAT = 4
var SETTINGS = 5
private var Content: ConstraintLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar!!.hide()
nav.show(HOME)
nav.setBackgroundColor(Color.TRANSPARENT)
abrirHome()
addOnMeowNavigattionBarIcons()
addOnNotificationInform()
chamarFragments()
}
fun abrirHome() {
val fragment = HomeFragment.newInstance()
addFragment(fragment)
}
fun addOnMeowNavigattionBarIcons() {
nav.add(MeowBottomNavigation.Model(MY_ACCOUNT, R.drawable.ic_baseline_account_circle_24))
nav.add(MeowBottomNavigation.Model(LIBRARY, R.drawable.ic_baseline_menu_book_24))
nav.add(MeowBottomNavigation.Model(HOME, R.drawable.ic_baseline_home_24))
nav.add(MeowBottomNavigation.Model(CHAT, R.drawable.ic_baseline_chat_24))
nav.add(MeowBottomNavigation.Model(SETTINGS, R.drawable.ic_baseline_settings_24))
}
fun addOnNotificationInform() {
nav.setCount(CHAT, "99")
}
fun chamarFragments() {
nav.setOnClickMenuListener {
when (it.id) {
HOME -> {
val fragment = HomeFragment.newInstance()
addFragment(fragment)
}
MY_ACCOUNT -> {
val fragment = MyAccountFragment.newInstance()
addFragment(fragment)
}
LIBRARY -> {
val fragment = LibraryFragment.newInstance()
addFragment(fragment)
}
CHAT -> {
val fragment = ChatFragment.newInstance()
addFragment(fragment)
}
SETTINGS -> {
val fragment = SettingsFragment.newInstance()
addFragment(fragment)
}
}
}
}
private fun addFragment(fragment: Fragment) {
supportFragmentManager
.beginTransaction()
.replace(R.id.parentfragments,fragment,fragment.javaClass.simpleName)
.addToBackStack(null)
.commit()
}
fun sair(view: View){
FirebaseAuth.getInstance().signOut()
val bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
val intent = Intent(this, login::class.java)
startActivity(intent,bundle)
}
}
This is the code of the fragment Library that has a SmartToolbar that calls two more fragments within it, MyLibrary and Store
class LibraryFragment: Fragment() {
companion object{
fun newInstance():LibraryFragment {
val args = Bundle()
val fragment = LibraryFragment()
fragment.arguments = args
return fragment
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.library_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val adapter = FragmentPagerItemAdapter(
fragmentManager, FragmentPagerItems.with(context)
.add("Minha Bilioteca", MyLibraryFragment::class.java)
.add("Loja", StoreFragment::class.java)
.create())
viewpager.adapter = adapter
viewpagertab.setViewPager(viewpager)
}
}
And this is the MyLibrary fragment that is shown inside the Library that is shown inside HomeActivity
class MyLibraryFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.mylibrary_fragment, container, false)
}
}
I couldn't implement list view in Fragment. I have just a ListView and ArrayList. My ArrayList is a String and takes 5 name.
class GroupFragment : Fragment() {
companion object {
fun newInstance(): GroupFragment {
return GroupFragment() } }
var arrayList= ArrayList<String>()
private lateinit var Adapter: ArrayAdapter<String>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_group, container, false)
val activity = activity as Context
val listview = view.findViewById<ListView>(R.id.list_view)
arrayList.add("Ajay")
arrayList.add("Vijay")
arrayList.add("Prakash")
arrayList.add("Rohan")
arrayList.add("Vijay")
Adapter = ArrayAdapter(activity, android.R.layout.simple_list_item_1,arrayList )
listview.adapter = ChatAdapter(activity, android.R.layout.simple_list_item_1, arrayList)
return view
}
class ChatAdapter(var mCtx: Context, var resources:Int, var items:List<String>):ArrayAdapter<String>(mCtx, resources, items) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val layoutInflater:LayoutInflater = LayoutInflater.from(mCtx)
val view:View = layoutInflater.inflate(resources, null)
val titleTextView: TextView = view.findViewById(R.id.textView)
var mItem: String = items[position]
titleTextView.text = mItem
return super.getView(position, convertView, parent)
}
}
}
My code as above but it returns nothing. I didn't understand why ?? Is it a problem "Adapter" ?? Is there any problem context ??
Can you try directly
listview.adapter = ArrayAdapter(activity, android.R.layout.simple_list_item_1,arrayList )