I am new to Mobile development. I have started my Mobile app with Kotlin. I have an Activity (ProductsActivity.kt) which loads RecyclerView with ImageView and TextView getting data from MySQL, which is working independently. Now, I want this Activity to load in Fragment, I tried to load using Inflater, but it doesn't show any data. Following is my code, please help how can I achieve the same. Thanks in advance.
MainActivity.kt
package com.example.administrator.zmaart
import android.content.Intent
import android.os.Bundle
import android.support.design.widget.NavigationView
import android.support.v4.app.Fragment
import android.support.v4.view.GravityCompat
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
class MainActivity : AppCompatActivity(),
NavigationView.OnNavigationItemSelectedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById<View>(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
val drawer = findViewById<View>(R.id.drawer_layout) as DrawerLayout
val toggle = ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close)
drawer.addDrawerListener(toggle)
toggle.syncState()
val navigationView = findViewById<View>(R.id.nav_view) as
NavigationView
navigationView.setNavigationItemSelectedListener(this)
displaySelectedScreen(R.id.nav_home)
}
private var backButtonCount: Int = 0
override fun onBackPressed() {
val drawer = findViewById<View>(R.id.drawer_layout) as DrawerLayout
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START)
} else {
if (backButtonCount >= 1) {
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_HOME)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
} else {
Toast.makeText(this, "Press the back button once again to close the application.", Toast.LENGTH_SHORT).show()
backButtonCount++
}
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
val id = item.itemId
return if (id == R.id.action_settings) {
true
} else super.onOptionsItemSelected(item)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
displaySelectedScreen(item.itemId)
return true
}
private fun displaySelectedScreen(itemId: Int) {
//creating fragment object
var fragment: Fragment? = null
//initializing the fragment object which is selected
when (itemId) {
R.id.nav_home -> fragment = home()
R.id.nav_orders -> fragment = orders()
R.id.nav_wishlist -> {
val intent = Intent(this#MainActivity,
ProductsActivity::class.java)
this#MainActivity.startActivity(intent)
}
R.id.nav_logout -> {
val sharedPreferences = getSharedPreferences("SharedPref", 0)
val editor = sharedPreferences.edit()
editor.clear()
editor.apply()
val intent = Intent(this#MainActivity, Login_Page::class.java)
this#MainActivity.startActivity(intent)
}
}
//replacing the fragment
if (fragment != null) {
val ft = supportFragmentManager.beginTransaction()
ft.replace(R.id.content_frame, fragment)
ft.commit()
}
val drawer = findViewById<View>(R.id.drawer_layout) as DrawerLayout
drawer.closeDrawer(GravityCompat.START)
}
}
activity_products.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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=".ProductsActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recylcerView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="745dp"
tools:layout_editor_absoluteY="-51dp" />
</RelativeLayout>
ProductsActivity.kt
package com.example.administrator.zmaart
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONArray
import org.json.JSONException
import java.util.*
class ProductsActivity : AppCompatActivity() {
private lateinit var productList: MutableList<Product>
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_products)
recyclerView = findViewById(R.id.recylcerView1)
recyclerView.setHasFixedSize(false)
recyclerView.layoutManager = LinearLayoutManager(this)
productList = ArrayList()
loadProducts()
}
private fun loadProducts() {
/*
* Creating a String Request
* The request type is GET defined by first parameter
* The URL is defined in the second parameter
* Then we have a Response Listener and a Error Listener
* In response listener we will get the JSON response as a String
* */
val stringRequest = StringRequest(Request.Method.GET, URL_PRODUCTS,
Response.Listener { response ->
try {
//converting the string to json array object
val array = JSONArray(response)
//traversing through all the object
for (i in 0 until array.length()) {
//getting product object from json array
val product = array.getJSONObject(i)
//adding the product to product list
productList.add(Product(
product.getString("prod_id_sha"),
product.getString("prod_title"),
product.getDouble("prod_price"),
product.getDouble("prod_price2"),
product.getString("img_thumbnail")
))
}
//creating adapter object and setting it to recyclerview
val adapter = ProductsAdapter(this#ProductsActivity, productList)
recyclerView.adapter = adapter
} catch (e: JSONException) {
e.printStackTrace()
}
},
Response.ErrorListener { })
//adding our stringrequest to queue
Volley.newRequestQueue(this).add(stringRequest)
}
companion object {
//this is the JSON Data URL
//make sure you are using the correct ip else it will not work
private const val URL_PRODUCTS = "localhost/app/load_prod.php"
}
}
home.kt (where I want to load activity_products.xml)
package com.example.administrator.zmaart
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
class home : Fragment() {
private lateinit var productList: MutableList<Product>
private lateinit var recyclerView: RecyclerView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.activity_products, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity!!.title = "Home"
}
}
Please let me know if any other code(s) to be included to help you to help me.
Related
I am new to Kotlin and to programming too.
RestaurantModel.kt
package com.example.foodtogo.model
import android.os.Parcel
import android.os.Parcelable
import java.io.Serializable
class RestaurantModel(val name:String?, val address:String?, val delivery_charge: Int, val image: String?, val open: String?,
var menus: List<Menus?>?): Serializable {}
class Menus(val name:String?, val price: Float, val url:String?, var totalInCart: Int):Serializable {}
RestaurantMainActivity.kt
package com.example.foodtogo
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.foodtogo.databinding.ActivityRestaurantMainBinding
import com.example.foodtogo.model.RestaurantModel
import com.example.foodtogo.view.RestaurantListAdapter
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import android.content.Intent as Intent
class RestaurantMainActivity : AppCompatActivity(){
private lateinit var binding: ActivityRestaurantMainBinding
private lateinit var firebaseAuth: FirebaseAuth
private lateinit var database: FirebaseDatabase
private lateinit var reference: DatabaseReference
private lateinit var restaurantList: ArrayList<RestaurantModel>
//var adapter: RestaurantListAdapter?=null
//private lateinit var restaurantList: MutableList<RestaurantModel?>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRestaurantMainBinding.inflate(layoutInflater)
setContentView(binding.root)
firebaseAuth = FirebaseAuth.getInstance()
database = FirebaseDatabase.getInstance()
reference = database.reference
Log.e("AKSA", "TEST1")
binding.recyclerViewRestaurant.layoutManager = LinearLayoutManager(this)
Log.e("AKSA", "TEST")
restaurantList = arrayListOf<RestaurantModel>()
getRestaurantData()
Log.e("AKSA", "TEST3")
}
private fun getRestaurantData() {
reference=FirebaseDatabase.getInstance().getReference("RestaurantModel")
reference.addValueEventListener(object : ValueEventListener,RestaurantListAdapter.ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
Log.e("AKSA", "TEST6")
Log.e("AKSA", "TEST $snapshot")
if (snapshot.exists()) {
Log.e("AKSA", "TEST00")
for (userSnapshot in snapshot.children) {
Log.e("AKSA", "TEST01")
val user =
userSnapshot.child("RestaurantModel").getValue(RestaurantModel::class.java)
Log.e("AKSA", "TEST02")
if (user != null) {
Log.e("AKSA", "TEST03")
restaurantList.add(user)
}
}
val adapter = RestaurantListAdapter(restaurantList, this)
binding.recyclerViewRestaurant.adapter = adapter
adapter.notifyDataSetChanged()
}
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(applicationContext, error.getMessage(), Toast.LENGTH_LONG).show()
}
override fun onItemClick(restaurantModel: RestaurantModel) {
val intent = Intent(applicationContext,RestaurantMenuActivity::class.java)
intent.putExtra("RestaurantModel", restaurantModel)
startActivity(intent)
Log.d("AKSA", "MESSAGE")
}
})
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menubar, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.home_menu -> {
val intent = Intent(this, ViewOrderActivity::class.java)
startActivity(intent)
}
R.id.signout_menu -> {
firebaseAuth.signOut()
val intent = Intent(this, LOGIN::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finish()
}
}
return super.onOptionsItemSelected(item)
}
}
RestaurantListAdapter.kt
package com.example.foodtogo.view
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.foodtogo.R
import com.example.foodtogo.model.RestaurantModel
import com.google.firebase.database.ValueEventListener
class RestaurantListAdapter(val restaurantList: ArrayList<RestaurantModel>, val clickListener: ValueEventListener):
RecyclerView.Adapter<RestaurantListAdapter.MyViewHolder>() {
//private lateinit var database: FirebaseDatabase
//private lateinit var reference:DatabaseReference
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RestaurantListAdapter.MyViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.recycler_restaurantlist,parent,false)
return MyViewHolder(view)
}
override fun onBindViewHolder(holder: RestaurantListAdapter.MyViewHolder, position: Int) {
holder.bind(restaurantList.get(position))
holder.itemView.setOnClickListener{
clickListener.onItemClick(restaurantList.get(position))
}
}
override fun getItemCount(): Int {
return restaurantList.size
}
inner class MyViewHolder(view: View):RecyclerView.ViewHolder(view){
val thumbImage: ImageView =view.findViewById(R.id.thumbImage)
val restaurantName: TextView =view.findViewById(R.id.restaurantName)
val restaurantAddress:TextView=view.findViewById(R.id.restaurantAddress)
val restaurantHours:TextView=view.findViewById(R.id.restaurantHours)
fun bind(restaurantModel: RestaurantModel?){
restaurantName.text=restaurantModel?.name
restaurantAddress.text="Address: "+restaurantModel?.address
restaurantHours.text="Open: "+restaurantModel?.open
Glide.with(this.thumbImage).load(restaurantModel?.image).centerCrop().placeholder(R.drawable.ic_launcher_background).into(thumbImage)
}
}
interface ValueEventListener {
fun onItemClick(restaurantModel: RestaurantModel)
}
}
"Log.e("AKSA", "TEST02")". Till this prints. But after this, user shows null value. First I used parcelize in the RestaurantModel.kt, later I changed and add serializable. I checked other programs too. But I am stuck. I don't understand where it goes wrong.
To solve the issue please use the following lines of code:
val db = Firebase.database.reference
val restaurantModelRef = db.child("RestaurantModel")
restaurantModelRef.get().addOnCompleteListener {
if (it.isSuccessful) {
val snapshot = it.result
for (restaurant in snapshot.children) {
val restaurantModel = restaurant.getValue(RestaurantModel::class.java)
restaurantList.add(restaurantModel)
}
val adapter = RestaurantListAdapter(restaurantList, getApplicationContext())
binding.recyclerViewRestaurant.adapter = adapter
adapter.notifyDataSetChanged()
}
}
Things to notice:
I have used get() instead of addValueEventListener().
There is no need to call child() on the DataSnapshot object inside the callback.
It will be more convenient to create an adapter with an empty list, and inside the callback just to notify about the changes.
i had a code where i used kotlin syntetic and it didnt work enymore on my app i have an error that is " lateinit property binding has not been initialized" i hanged added only private lateinit var binding: ActivityMainBinding and i changed the uzytkownik.text = sb.toString() to binding.uzytkownik.text = sb.toString() becouse that what i have found what to do but the rest of private fun retrivePerson() is harder to me
my collection name what i wanna to show in firebase is uzytkownik
this is my code
package com.example.nfc
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.widget.Button
import android.widget.ScrollView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.nfc.databinding.ActivityMainBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.ktx.toObject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.tasks.await
import java.lang.StringBuilder
class MainActivity : AppCompatActivity() {
private val personCollectionName = Firebase.firestore.collection("uzytkownik")
private lateinit var binding: ActivityMainBinding
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
auth = Firebase.auth
val addButton = findViewById<Button>(R.id.addButton)
addButton.setOnClickListener {
val intent = Intent(this, addtrasa::class.java)
startActivity(intent)
}
val btnRetrieveData = findViewById<Button>(R.id.btnRetrieveData)
btnRetrieveData.setOnClickListener {
retrivePerson()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
auth.signOut()
val logoutIntent = Intent(this, loginActivity::class.java)
logoutIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(logoutIntent)
Toast.makeText(this, "ZostaĆes wylogowany", Toast.LENGTH_SHORT).show()
return super.onOptionsItemSelected(item)
}
private fun retrivePerson() = CoroutineScope(Dispatchers.IO).launch {
try {
val querySnapshot = personCollectionName.get().await()
val sb = StringBuilder()
for (document in querySnapshot.documents) {
val users = document.toObject<users>()
sb.append("$users\n")
}
withContext(Dispatchers.Main) {
binding.uzytkownik.text = sb.toString()
}
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(this#MainActivity, e.message, Toast.LENGTH_LONG).show()
}
}
}
}
my scrollview where i wanna it o show its
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="245dp"
android:layout_height="66dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/uzytkownik"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Witaj,"
android:textColor="#android:color/black"
android:textSize="18sp" />
</ScrollView>
I have got an error about no such talbe: Account while I am calling data from database.
My database name is "account.db" and table name is "Account". There are two columns, first is "name" and second is "email".
I am writing in kotlin language. Please look at below for my DBHelper and DBManager.
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.os.Build
import android.widget.Toast
import java.io.FileOutputStream
import java.io.IOException
import java.lang.Exception
import java.util.ArrayList
class DbManager {
var DB_PATH = ""
var DB_NAME = "account.db"
val dbVersion = 1
//CREATE TABLE IF NOT EXISTS MyNotes (ID INTEGER PRIMARY KEY,title TEXT, Description TEXT);"
// val sqlCreateTable = "CREATE TABLE IF NOT EXISTS " + dbTable + " (" + colID + " INTEGER PRIMARY KEY," +
// colTitle + " TEXT, " + colDes + " TEXT);"
var sqlDB: SQLiteDatabase? = null
constructor(context: Context) {
var db = DBHelper(context)
sqlDB = db.writableDatabase
}
inner class DBHelper(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, dbVersion) {
var mDatabase: SQLiteDatabase? = null
var mContext: Context? = null
//Todo: Get All Data users
fun getAllUsers(): List<Account>?{
val temp = ArrayList<Account>()
val db = writableDatabase
var c: Cursor?
try {
c = db.rawQuery("SELECT * FROM Account ", null)
if (c == null) return null
c.moveToFirst()
do {
val account = Account(c.getString(c.getColumnIndex("name")), c.getString(c.getColumnIndex("email")))
temp.add(account)
} while (c.moveToNext())
c.close()
} catch (e: Exception) {
}
db.close()
return temp
}
fun createDataBase() {
//Todo: Create Database
val isDBExist = checkDataBase()
if (isDBExist) { } else {
this.readableDatabase
try {
copyDataBase()
Toast.makeText(this.mContext, "Copy has been finished.", Toast.LENGTH_SHORT).show()
} catch (ex: Exception) {
}
}
}
init {
if (Build.VERSION.SDK_INT > 17) {
DB_PATH = context.applicationInfo.dataDir + "/databases/"
} else {
DB_PATH = "/data/data/" + context.packageName + "/databases/"
}
this.mContext = mContext
}
override fun close() {
if (mDatabase != null)
mDatabase!!.close()
super.close()
}
fun checkDataBase(): Boolean {
//Todo: Check Database
var tempDB: SQLiteDatabase? = null
try {
val path = DB_PATH + DB_NAME
tempDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY)
} catch (ex: Exception) {
}
if (tempDB != null)
tempDB.close()
return if (tempDB != null) true else false
}
fun copyDataBase() {
//Todo:Copy Database
try {
val myInput = mContext!!.assets.open(DB_NAME)
val outputFileName = DB_PATH + DB_NAME
val myOutput = FileOutputStream(outputFileName)
val buffer = ByteArray(1024)
var length: Int
length= myInput.read(buffer)
while (length > 0) {
myOutput.write(buffer, 0, length)
}
myOutput.flush()
myOutput.close()
myInput.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
fun openDataBase() {
//Todo: Open Database
val path = DB_PATH + DB_NAME
mDatabase = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE)
}
override fun onCreate(db: SQLiteDatabase) {
createDataBase()
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
if(oldVersion>=newVersion){
copyDataBase()
}
}
// companion object {
// var DB_PATH = ""
// var DB_NAME = "account.db"
// }
}
}
Here is my MainActivity.kt
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.row.*
import kotlinx.android.synthetic.main.row.view.*
import java.util.ArrayList
class MainActivity : AppCompatActivity() {
var lstUsers=ArrayList<Account>()
lateinit var dbHelper: DBHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dbHelper = DBHelper(applicationContext)
dbHelper.createDataBase()
}
fun buGetData(v: View){
//Todo: Load Data from db set to listview
LoadData()
}
fun LoadData(){
val accout = dbHelper.getAllUsers()
//this.listView.removeAllViews()
//List View
for (list in accout!!) {
lstUsers.add(list)
}
var myNotesAdapter= MyAdapter(this, lstUsers)
listView.adapter=myNotesAdapter
}
inner class MyAdapter:BaseAdapter {
var listMyAdapter = ArrayList<Account>()
var context:Context?=null
constructor(context:Context, listMyAdapter:ArrayList<Account>):super(){
this.listMyAdapter=listMyAdapter
this.context=context
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var myView=layoutInflater.inflate(R.layout.row,null)
var myAc=listMyAdapter[position]
myView.txtUser.text = myAc.userName
myView.txtEmail.text = myAc.email
return myView
}
override fun getItem(position: Int): Any {
return listMyAdapter[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return listMyAdapter.size
}
}
}
The error has shown like the picture below.
Please help me to solve it. Best regards, Sai Tawng Pha
I have solved my problem with update a few line of code. I want to share for other people.
If some one want to read exist Database file from Assests folder with Kotlin. Please have look below.
MainActivity.kt
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.row.*
import kotlinx.android.synthetic.main.row.view.*
import java.util.ArrayList
class MainActivity : AppCompatActivity() {
var lstUsers=ArrayList<Account>()
var dbHelper: DBHelper? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dbHelper = DBHelper(this)
dbHelper!!.createDatabase()
}
fun buGetData(v: View){
lstUsers = this.dbHelper!!.getAllUsers() as ArrayList<Account>
this.container.removeAllViews()
//List View
for (account in lstUsers) {
// val inflater = baseContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
// val addView = inflater.inflate(R.layout.row, null)
var addView = layoutInflater.inflate(R.layout.row,null)
addView.txtUser.text = account.userName
addView.txtEmail.text = account.email
//add View
container.addView(addView)
}
}
}
DBHelper.kt
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class DbHelper extends SQLiteOpenHelper {
private static String DB_PATH= "";
private static String DB_NAME= "account.db";
private SQLiteDatabase mDatabase;
private final Context mContext;
public DbHelper(Context context) {
super(context, DB_NAME, null, 11);
this.mContext = context;
if(Build.VERSION.SDK_INT >= 17){
this.DB_PATH = context.getApplicationInfo().dataDir+"/databases/";
Log.e("Path:", DB_PATH);
}else {
this.DB_PATH = "/data/data/"+context.getPackageName()+"/databases/";
Log.e("Path:", DB_PATH);
}
}
#Override
public synchronized void close() {
if(mDatabase != null){
mDatabase.close();
}
super.close();
}
private boolean checkDatabase(){
//Todo: Check Database
SQLiteDatabase tempDB = null;
try {
String path = DB_PATH+DB_NAME;
tempDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
}catch (Exception ex){}
if(tempDB!=null){
tempDB.close();
}
return tempDB!=null?true:false;
}
public void copyDatabase(){
//Todo: Copy Database
try {
InputStream myInput = mContext.getAssets().open(DB_NAME);
String outputFileName = DB_PATH+DB_NAME;
OutputStream myOutput = new FileOutputStream(outputFileName);
byte[] buffer = new byte[1024];
int length;
while ((length=myInput.read(buffer))>0){
myOutput.write(buffer,0,length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void openDatabase(){
//Todo: Open Database
String path = DB_PATH+DB_NAME;
mDatabase = SQLiteDatabase.openDatabase(path,null, SQLiteDatabase.OPEN_READWRITE);
}
public void createDatabase(){
//Todo: Create Database
boolean isDBExist = checkDatabase();
if (isDBExist){
}else {
this.getReadableDatabase();
try {
copyDatabase();
}catch (Exception e){throw new Error("Copy Database Error");}
}
}
public List<Account>getAllUsers(){
//Todo: Get All Users
List<Account> temp = new ArrayList<Account>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c;
try {
c = db.rawQuery("SELECT * FROM Account", null);
if (c==null) return null;
c.moveToFirst();
do {
Account account = new Account(c.getString(c.getColumnIndex("name")),(c.getString(c.getColumnIndex("email"))));
temp.add(account);
}while (c.moveToNext());
c.close();
}catch (Exception e){}
db.close();
return temp;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<Button
android:id="#+id/buGetData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="Get Data" />
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/buGetData"
android:layout_centerHorizontal="true"
android:layout_marginTop="-15dp"
android:orientation="vertical"></LinearLayout>
</RelativeLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txtUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="TextView"
android:textSize="18sp" />
<TextView
android:id="#+id/txtEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="TextView" />
</LinearLayout>
Please look the screenshot below.
Note: Please replace your Database file from Assets folder and change the name of your database name and table name from DBHelper.kt at createDataBase Function.
I hope, it will be useful for you.
I really don't know where I am going wrong. According to the documentation I am doing everything right. I am doubtful if it's happening just because I am using TabbedActivity and dealing with fragments, but still I don't know how it's wrong.
Please look into the code and help me out. I have been struggling a lot to achieve this task of retrieving and displaying data from FIREBASE.
And being a beginner in this, it's quite hard for me to figure it out.
MainActivity.Java
package com.example.souravkumar.sqaurewallpapers;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
public class MainActivity extends AppCompatActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
int count=0;
public FloatingActionButton mAddImage;
private StorageReference mStorage;
public DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
String stringUri;
Long date;
private static final int GALLERY_INTENT = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
mStorage = FirebaseStorage.getInstance().getReference();
mAddImage = (FloatingActionButton) findViewById(R.id.addImage);
mAddImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, GALLERY_INTENT);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_INTENT && resultCode == RESULT_OK) {
Uri uri = data.getData();
StorageReference filePath = mStorage.child("Wallpapers").child(uri.getLastPathSegment());
filePath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(MainActivity.this, "Upload Successful", Toast.LENGTH_LONG).show();
Uri downloadUrl = taskSnapshot.getDownloadUrl();
//Adding image to the database
stringUri= downloadUrl.toString();
date = System.currentTimeMillis();
addImageToDatabase (stringUri, date);
}
});
}
}
private void addImageToDatabase(String downloadUrl, Long date){
image_details id= new image_details(downloadUrl, date);
String key = mDatabase.push().getKey();
mDatabase.child(key).child("URL").setValue(id.getUrl());
mDatabase.child(key).child("Date").setValue(id.getDate());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
GridView gridView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
View rootView = inflater.inflate(R.layout.fragment_popular, container, false);
return rootView;
} else if (getArguments().getInt(ARG_SECTION_NUMBER) == 2) {
View rootView = inflater.inflate(R.layout.fragment_recent, container, false);
return rootView;
} else
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "POPULAR";
case 1:
return "RECENT";
case 2:
return "PROFILES";
}
return null;
}
}
}
Popular.Java
package com.example.souravkumar.sqaurewallpapers;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;
/**
* Created by Sourav Kumar on 11/3/2017.
*/
public class popular extends FragmentActivity {
private RecyclerView recyclerView;
private DatabaseReference myRef;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
myRef = FirebaseDatabase.getInstance().getReference();
FirebaseRecyclerAdapter<image_details,BlogViewHolder> recyclerAdapter=new FirebaseRecyclerAdapter<image_details,BlogViewHolder>(
image_details.class,
R.layout.individual_row,
BlogViewHolder.class,
myRef
) {
#Override
protected void populateViewHolder(BlogViewHolder viewHolder, image_details model, int position) {
viewHolder.setUrl(model.getUrl());
viewHolder.setDate(model.getDate());
}
};
recyclerView.setAdapter(recyclerAdapter);
}
public static class BlogViewHolder extends RecyclerView.ViewHolder {
View mView;
TextView textView;
ImageView imageView;
public BlogViewHolder(View itemView) {
super(itemView);
mView=itemView;
textView = (TextView)itemView.findViewById(R.id.date);
imageView = (ImageView)itemView.findViewById(R.id.imageView);
}
public void setDate(Long date) {
textView.setText(date.toString());
}
public void setUrl(String url) {
Picasso.with(mView.getContext())
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView);
}
}
}
image_details.Java
package com.example.souravkumar.sqaurewallpapers;
/**
* Created by Sourav Kumar on 10/29/2017.
*/
public class image_details {
String url;
Long date;
image_details(){}
public image_details(String url, Long date){
this.url = url;
this.date = date;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Long getDate() {
return date;
}
public void setDate(Long date) {
this.date = date;
}
}
fragment_popular.xml
<RelativeLayout 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.souravkumar.sqaurewallpapers.popular">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerView">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
individual_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="150dp"
android:layout_height="280dp"
android:id="#+id/imageView"
android:src="#mipmap/ic_launcher"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Date"
android:id="#+id/date"/>
</LinearLayout>
</android.support.v7.widget.CardView>
I am using the default Navigation Drawer in android studio and I have a dynamically created fragment and use TabLayout to run it. It will run normally but as I try to load the same fragment from the navigation drawer i run into error. Please see below:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class Introduction extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final RelativeLayout relativeLayout = new RelativeLayout(getActivity());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
relativeLayout.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
final ImageView introImage = new ImageView(getActivity());
introImage.setId(R.id.introImageId);
introImage.setImageResource(R.drawable.introduction);
introImage.setAnimation(AnimationUtils.loadAnimation(this.getContext(), android.R.anim.slide_out_right));
introImage.setPadding(100, 100, 100, 100);
final TextView introText = new TextView(getActivity());
introText.setText(R.string.introduction_text);
// introText.setTextAppearance(android.R.style.TextAppearance_Medium);
introText.setTextSize(20);
introText.setPadding(25,25,25,25);
introText.setTextColor(ContextCompat.getColor(this.getContext(), R.color.colorPrimary));
params.addRule(RelativeLayout.BELOW, introImage.getId());
introText.setAnimation(AnimationUtils.loadAnimation(this.getContext(),android.R.anim.slide_in_left));
relativeLayout.addView(introText,params);
relativeLayout.addView(introImage);
return relativeLayout;
}
}
But as I try to load it from Navigation drawer I get an error Error:(115, 62) error: incompatible types: Introduction cannot be converted to Fragment
public boolean onNavigationItemSelected(MenuItem item) {
FragmentManager fn = getFragmentManager();
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_introduction) {
fn.beginTransaction().replace(R.id.content_frame,new Introduction()).commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
TabPagerAdapter
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabPagerAdapter extends FragmentPagerAdapter {
int tabCount;
public TabPagerAdapter(FragmentManager fm, int numberOfTabs) {
super(fm);
this.tabCount=numberOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
Introduction tab1= new Introduction();
return tab1;
default:
return null;
}
}
I replaced getFragmentManager(); with getSupportFragmentManager(); and its working
// FragmentManager fn = getFragmentManager();
FragmentManager fn = getSupportFragmentManager();