How to get a variable from another class in kotlin? - android

I want to get a variable from an activity and use it in another class.
This variable will be filled by an user in a editText that is called editTextSerie
override fun searchSeries(listener: OnDataListener) {
val retrofit = Retrofit.Builder().addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://api.themoviedb.org/3/")
.build()
val client = retrofit.create(MovieDBApiInterface::class.java)
val objetoClasse1 = SearchActivity()
var nomeS = objetoClasse1.editTextSerie.text.toString().trim()
val responseCall = client.searchSeries("API_KEY", "pt-BR", nomeS)
responseCall.enqueue(object : Callback<AllSeriesResponse> {
override fun onResponse(call: Call<AllSeriesResponse>?, response1: Response<AllSeriesResponse>?) {
listener.onSuccess(response1!!.body()!!.results)
}
override fun onFailure(call: Call<AllSeriesResponse>?, t: Throwable?) {
listener.onFailure(t!!.message.toString())
}
})
}
This function "searchSeries" is from the class "Series".
I want to get the "editTextSerie" from another class called "Search Activity",
so i created the variable "nomeS" to receive the value of it.
class SearchActivity : AppCompatActivity() {
var botaoSearch: AppCompatImageButton? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
botaoSearch = findViewById(R.id.btn_search)
botaoSearch?.setOnClickListener {
var nomeSerie = editTextSerie.text.toString().trim()
}
}
}
I want to receive this value (value of editTextSerie comes from the XML of SearchActivity ) and use it at responseCall with the "nomeS" variable

What is OnDataListener? Not really sure it is interface or abstract class, so I' ll write some pseudo code.
First change your function searchSeries's params to
searchSeries(text: String, listener: OnDataListener)
So in the class Series, you can get the data in your function searchSeries:
override fun searchSeries(text: String, listener: OnDataListener) {
// ...
// you can get the "text" string
}
Then edit your SearActivity's listener:
class SearchActivity : AppCompatActivity() {
var botaoSearch: AppCompatImageButton? = null
// create class "Series"
val series = Series()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
botaoSearch = findViewById(R.id.btn_search)
botaoSearch?.setOnClickListener {
var nomeSeries = editTextSerie.text.toString().trim()
searchSeries(nomeSeries)
}
}
private fun searchSeries(text: String) {
series.searchSeries(text, object : OnDataListener {
override onSuccess(a0: ...) {
}
override onFailure(message: String) {
}
})
}
}
If OnDataListener is a abstract class:
series.searchSeries(text, object : OnDataListener() {
override onSuccess(a0: ...) {
}
override onFailure(message: String) {
}
})

Related

Android TV. How to implement getMainFragmentAdapter() method inside VerticalGridSupportFragment

I'm trying to integrate a VerticalGridSupportFragment() inside a BrowseSupportFragment() based on some of the Leanback examples.
On running the code below (partial snippet provided below) I get the exception java.lang.IllegalArgumentException: Fragment must implement MainFragmentAdapterProvider
I'm struggling to understand how to implement the interface methods defined by MainFragmentAdapterProvider [i.e getMainFragmentAdapter()]. Could anyone provide insight surrounding this issue, or could you provide an example? I've tried to return the mRowsAdapter, however it was not of the correct type.
Any help would really be appreciated, thanks!
class MainFragmentByGroupFragment : BrowseSupportFragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
Log.i(TAG, "onCreate")
super.onActivityCreated(savedInstanceState)
prepareBackgroundManager()
mainFragmentRegistry.registerFragment(
PageRow::class.java,
PageRowFragmentFactory(mBackgroundManager)
)
setupUIElements()
createRows()
setupEventListeners()
}
private class PageRowFragmentFactory(backgroundManager: BackgroundManager) : BrowseSupportFragment.FragmentFactory<androidx.fragment.app.Fragment>() {
override fun createFragment(rowObj: Any?): androidx.fragment.app.Fragment {
val row = rowObj as Row
return ChannelFragment()
}
}
}
class ChannelFragment : VerticalGridSupportFragment(), OnItemViewClickedListener, BrowseSupportFragment.MainFragmentAdapterProvider {
private var mRowsAdapter: ArrayObjectAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mRowsAdapter = ArrayObjectAdapter(CardPresenter())
setAdapter(mRowsAdapter)
setOnItemViewClickedListener(this)
createRows()
}
private fun createRows() {
val gridPresenter = VerticalGridPresenter()
gridPresenter.numberOfColumns = NUM_COLUMNS
setGridPresenter(gridPresenter)
setOnItemViewClickedListener(this)
val list = MovieList.list
for (i in 0 until 100) {
mRowsAdapter!!.add(list[i % 5])
}
}
override fun onItemClicked(
itemViewHolder: Presenter.ViewHolder?, item: Any,
rowViewHolder: RowPresenter.ViewHolder?, row: Row?
) {
}
override fun getMainFragmentAdapter(): BrowseSupportFragment.MainFragmentAdapter<*> {
TODO("Not yet implemented")
}
companion object {
private const val NUM_COLUMNS = 5
}
}
I think you should implement getMainFragmentAdapter.
Add the following to ChannelFragment:
private val mMainFragmentAdapter: BrowseSupportFragment.MainFragmentAdapter<*> =
object : BrowseSupportFragment.MainFragmentAdapter<Fragment?>(this) {
override fun setEntranceTransitionState(state: Boolean) {
}
}
And return mMainFragmentAdapter in getMainFragmentAdapter:
override fun getMainFragmentAdapter(): BrowseSupportFragment.MainFragmentAdapter<*> {
return mMainFragmentAdapter
}

Configuration Changes Not Save App State MVVM

I am building a movie app. There is a recyclerview matching parent size,and 1 search action button(SearchView).
When I search for a movie,everything is working fine,but when I change orientation,the activity just lose it's state. the recyclerview turns empty and I need to search for the movie again.
I am using MVVM and I know its not suppose to happen..
Thank you!
This is the Repository:
class MainRepository {
private val searchAfterMutableLiveData = MutableLiveData<List<Movie>>()
private val apiService : GetFromApi = APIService.retrofitClientRequest
private val apiKey = "censored"
fun searchAfter(searchAfter : String) : MutableLiveData<List<Movie>>{
apiService.searchAfter(apiKey,searchAfter)?.enqueue(object : Callback<MovieListResult?> {
override fun onResponse(
call: Call<MovieListResult?>,
response: Response<MovieListResult?>
) {
if (response.isSuccessful){
searchAfterMutableLiveData.value = response.body()?.moviesResults
Log.e("SearchMovieListResults","Result: ${searchAfterMutableLiveData.value}")
}
}
override fun onFailure(call: Call<MovieListResult?>, t: Throwable) {
Log.e("SearchMovieListResults","Failed: ${t.message}")
}
})
return searchAfterMutableLiveData
}
}
This is the ViewModel:
class MainViewModel : ViewModel(){
fun getMovieBySearch(searchAfter : String) : LiveData<List<Movie>>{
return mainRepository.searchAfter(searchAfter)
}
}
This is the MainActivity:
class MainActivity : AppCompatActivity() {
private val mainViewModel : MainViewModel by viewModels()
private lateinit var mainRecyclerView : RecyclerView
private lateinit var mainAdapter : MainRecyclerViewAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initRecyclerView()
}
private fun initRecyclerView() {
mainRecyclerView = findViewById(R.id.mainRecyclerView)
mainRecyclerView.setHasFixedSize(true)
mainRecyclerView.layoutManager = GridLayoutManager(this,1)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu,menu)
val searchView = menu.findItem(R.id.menu_search_movie).actionView as androidx.appcompat.widget.SearchView
searchView.queryHint = "Search By Name,Actor .."
searchView.setOnQueryTextListener(object : androidx.appcompat.widget.SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(whileTextChange: String?): Boolean {
//Clear SearchView
searchView.isIconified = true
searchView.setQuery("", false)
searchView.onActionViewCollapsed()
mainViewModel.getMovieBySearch(whileTextChange.toString()).observe(this#MainActivity,object : Observer<List<Movie>?> {
override fun onChanged(newList: List<Movie>?) {
if (newList != null) {
mainAdapter = MainRecyclerViewAdapter(newList)
mainRecyclerView.adapter = mainAdapter
//mainAdapter.changeCurrentList(newList)
}
}
})
return false
}
override fun onQueryTextChange(whileTextChange: String?): Boolean {
Log.e("onQueryTextChange","Text: $whileTextChange")
return false
}
})
return true
}
}
You need to save the desired state in the viewmodel. For example,
var persistedMovies = arrayListOf<Movie>()
and when the search returns a valid response,
mainViewModel.persistedMovies = newList
Now the list is scoped to the viewmodel and persists through orientation changes.

where I am making mistake in mainactivity?

I am developing android app and I am getting error screenshot below when I have implemented network call in mainactivity.kt I want to know where I am making mistake
below my MainActivity.kt
class MainActivity : AppCompatActivity() {
private var adapter: CurrenciesAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recycler_main.layoutManager = LinearLayoutManager(this#MainActivity)
adapter = CurrenciesAdapter(this)
recycler_main.adapter = adapter
if (isInternetAvailable()) {
getUsersData()
}
}
private fun getUsersData() {
showProgressBar()
var apiInterface: CurrenciesResponse = CurrencyClient().getApiClient()!!.create(
CurrenciesResponse::class.java
)
apiInterface.getCurrencies().enqueue(object : Callback <List<CurrencyResponse>> {
override fun onResponse(
call: Call<List<CurrencyResponse>>,
response: Response<List<CurrencyResponse>>)
{
hideProgressBar()
val currencyResponse = response.body()
adapter?.list = currencyResponse!!
}
override fun onFailure(call: Call<List<CurrencyResponse>>, t: Throwable) {
hideProgressBar()
Log.e("error", t.localizedMessage)
}
})
}
}
what I have done I have changed to response type from <List to CurrencyResponse but I am still getting response below whole gist code
https://gist.github.com/kyodgorbek/d0d9b3749ac64f15b4db87874cfe13e7
Your getCurrencies() method in CurrenciesResponse.class has a return type of CurrenciesResponse whereas it should be List<CurrenciesResponse>.
You need to fix your retrofit's service interface.

How to use the object value in another class in Kotlin and Microsoft Oauth 2.0

I want to use the below object in another class:
private var mSingleAccountApp: ISingleAccountPublicClientApplication? = null
PublicClientApplication.createSingleAccountPublicClientApplication(
this,
R.raw.auth_config_single_account,
object : IPublicClientApplication.ISingleAccountApplicationCreatedListener {
override fun onCreated(application: ISingleAccountPublicClientApplication) {
mSingleAccountApp = application
// loadAccount()
}
override fun onError(exception: MsalException) {
//txt_log.text = exception.toString()
}
}
)
I need to call the below method from another class
fun performOperationOnSignOut() {
mSingleAccountApp!!.signOut(object : ISingleAccountPublicClientApplication.SignOutCallback {
override fun onSignOut() {
}
override fun onError(exception: MsalException) {
//displayError(exception)
}
})
}
I tried to call but mSingleAccountApp always throws NullPointerException
How can I pass or use the mSingleAccountApp variable in another class?
ISingleAccountPublicClientApplication this is an interface
This is the simplest example I could come up with:
//class with one property
class Foo(val name : String){
}
class Bar(){
constructor(foo: Foo) : this() {
//access the property of the foo object
println(foo.name)
}
}
fun main() {
val foo = Foo("John Doe")
//pass foo-object in the constructor
val bar = Bar(foo)
}
see also: https://kotlinlang.org/docs/reference/properties.html
class CustomClass(var listener: ListenerAppImp){
private var mSingleAccountApp: ISingleAccountPublicClientApplication? = null
PublicClientApplication.createSingleAccountPublicClientApplication(
this,
R.raw.auth_config_single_account,
object : IPublicClientApplication.ISingleAccountApplicationCreatedListener {
override fun onCreated(application: ISingleAccountPublicClientApplication) {
mSingleAccountApp = application
listener.getAppValue(mSingleAccountApp) // todo mSingleAccountApp Value through interface
// loadAccount()
}
override fun onError(exception: MsalException) {
//txt_log.text = exception.toString()
}
}
)
}
// todo for example
interface ListenerAppImp {
fun getAppValue(mSingleAccountApp : ISingleAccountPublicClientApplication)
}
class User {
var customClass = CustomClass(object : ListenerAppImp{
override fun getAppValue(mSingleAccountApp: ISingleAccountPublicClientApplication) {
}
})
}
hope that may help you
In your case just implement interface ISingleAccountPublicClientApplication in another class for your understanding let's keep class name is Another
class Another : ISingleAccountPublicClientApplication {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
.....InitialiseYourInterfaceHere.....
}
override fun signOut(..yourcode...){
.......yourcode.......
}
}

How to access Application class variables in activity in kotlin android

I used to access application class private variables by using a
public methods in java
How to do the same using kotlin
App.kt
class App : Application() {
private var app: App? = null
private var movieAppComponent: MovieAppComponent? = null
override fun onCreate() {
super.onCreate()
app = this
movieAppComponent = DaggerMovieAppComponent.builder()
.applicationModule(ApplicationModule(this))
.netModule(NetModule(Keys.BASE_URL, this))
.build()
}
fun getApp(): App? {
return app
}
fun getMovieAppComponent(): MovieAppComponent? {
return movieAppComponent
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
App.getApp().getMovieAppComponent().inject(this)
}
}
Error:
App.getApp().getMovieAppComponent().inject(this)
Here getApp() i am getting as unresolved reference
Solution 1:
class App : Application() {
private var movieAppComponent: MovieAppComponent? = null
companion object {
private var app: App? = null
fun getApp(): App? {
return app
}
}
override fun onCreate() {
super.onCreate()
app = this
movieAppComponent = DaggerMovieAppComponent.builder()
.applicationModule(ApplicationModule(this))
.netModule(NetModule(Keys.BASE_URL, this))
.build()
}
fun getMovieAppComponent(): MovieAppComponent? {
return movieAppComponent
}
}
Solution 2:
No need to create such method. You can use type casting in your Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
(application as? App)?.getMovieAppComponent()?.inject(this)
}
}

Categories

Resources