THIS IS MY XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MakeComplaint.Category_Description"
android:background="#drawable/fragmentgradient_bg">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/heading_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteX="17dp">
<ImageView
android:id="#+id/backToHistory"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingHorizontal="20dp"
android:layout_weight="2"
android:src="#drawable/ic_backarrow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="#+id/location_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/location_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingHorizontal="20dp"
android:fontFamily="#font/pathway_gothic_one"
android:gravity="center"
android:textSize="40sp"
android:text="Further Details"
app:layout_constraintHorizontal_bias="0.35"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#+id/backToHistory"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.cardview.widget.CardView
android:id="#+id/details_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="#dimen/card_spacing"
app:cardUseCompatPadding="true"
app:layout_constraintTop_toBottomOf="#+id/heading_constraint"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:cardCornerRadius="#dimen/card_spacing"
>
<ScrollView
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/inner_constraint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/card_spacing">
<TextView
android:id="#+id/guide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/pathway_gothic_one"
android:gravity="left"
android:text="Please enter any further details you would like to add:"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/description_text_input"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:boxStrokeColor="#color/teal"
app:boxStrokeWidth="#dimen/card_spacing"
app:counterEnabled="true"
app:counterMaxLength="500"
android:hint="Additional Notes"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/guide"
app:prefixTextColor="#color/colorPrimaryDark"
android:outlineAmbientShadowColor="#color/teal"
android:outlineSpotShadowColor="#color/teal"
android:scrollbarAlwaysDrawHorizontalTrack="true"
app:layout_constraintBaseline_creator="#android:integer/config_longAnimTime"
>
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences|textMultiLine"
android:maxLength="500"
/>
</com.google.android.material.textfield.TextInputLayout>
<!--ImageView where image will be set-->
<ImageView
android:id="#+id/display_image"
android:scaleType="centerCrop"
android:layout_width="250dp"
android:layout_height="250dp"
android:adjustViewBounds="true"
app:layout_constraintTop_toBottomOf="#+id/description_text_input"
app:layout_constraintBottom_toTopOf="#+id/FAB_buttons"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/FAB_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/description_text_input"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginVertical="5dp">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:backgroundTint="#color/teal"
android:layout_marginHorizontal="#dimen/card_spacing"
android:src="#android:drawable/ic_menu_camera"
app:layout_constraintRight_toLeftOf="#+id/camera"
app:layout_constraintTop_toBottomOf="#+id/name_text_input"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/upload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:backgroundTint="#color/teal"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/name_text_input"
android:src="#android:drawable/ic_menu_gallery"
/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Make Complaint"
app:layout_constraintTop_toBottomOf="#+id/FAB_buttons"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:backgroundTint="#color/teal"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>```
**THIS IS MY KOTLIN FILE**
package com.example.atry.MakeComplaint
class Category_Description : Fragment() {
private val ALL_PERMISSIONS_RESULT = 107
private val IMAGE_RESULT = 200
private val REQUEST_IMAGE_CAPTURE = 12345
var mBitmap: Bitmap? = null
val permission = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(com.example.atry.R.layout.fragment_category__description, container, false)
val camera_FAB: View = v.findViewById(com.example.atry.R.id.camera)
val upload_FAB: View = v.findViewById(com.example.atry.R.id.upload)
val imageView = v.findViewById<ImageView>(com.example.atry.R.id.display_image)
upload_FAB.setOnClickListener {
pickImageFromGallery()
}
camera_FAB.setOnClickListener{
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val frag = this
/** Pass your fragment reference **/
frag.startActivityForResult(
intent,
REQUEST_IMAGE_CAPTURE
) // REQUEST_IMAGE_CAPTURE = 12345
}
fun hasPermissionInManifest(context: Context, permissionName: String): Boolean {
val packageName = context.packageName
try {
val packageInfo = context.packageManager
.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
val declaredPermisisons = packageInfo.requestedPermissions
if (declaredPermisisons != null && declaredPermisisons.size > 0) {
for (p in declaredPermisisons) {
if (p == permissionName) {
return true
}
}
}
} catch (e: PackageManager.NameNotFoundException) {
}
return false
}
v.backToHistory.setOnClickListener {
backFragment()
}
// Inflate the layout for this fragment
return v
}
private fun pickImageFromGallery() {
//Intent to pick image
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, IMAGE_PICK_CODE)
}
companion object {
//image pick code
private val IMAGE_PICK_CODE = 1000;
//Permission code
private val PERMISSION_CODE = 1001;
}
private fun backFragment() {
val manager = (context as AppCompatActivity).supportFragmentManager
manager.popBackStackImmediate()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data !=null) {
if (requestCode == REQUEST_IMAGE_CAPTURE || requestCode== IMAGE_PICK_CODE) {
// Do something with imagePath
val extras = data.getExtras()
val photo = extras.get("data") as Bitmap
val imageView = view!!.findViewById<ImageView>(com.example.atry.R.id.display_image)
imageView.setImageBitmap(photo)
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
var selectedImage = activity.let { getImageUri( it!!,photo) }
val realPath = selectedImage.let { getRealPathFromURI(it) }
selectedImage = Uri.parse(realPath)
}
}
super.onActivityResult(requestCode, resultCode, data)
}
fun getImageUri(inContext: Context, inImage: Bitmap): Uri {
val bytes = ByteArrayOutputStream()
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
val path =
MediaStore.Images.Media.insertImage(inContext.contentResolver, inImage, "Title", null)
return Uri.parse(path)
}
fun getRealPathFromURI(contentUri: Uri): String {
var cursor: Cursor? = null
try {
val proj = arrayOf(MediaStore.Images.Media.DATA)
cursor = getActivity()?.getContentResolver()?.query(contentUri, proj, null, null, null)
val column_index = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor!!.moveToFirst()
return cursor!!.getString(column_index)
} finally {
if (cursor != null) {
cursor!!.close()
}
}
}
}```
For capturing the image everything works fine until the screen appears where I click on the tick to approve that the picture is okay...but then I am unable to view anything on the ImageView.
For the upload button when I am on the screen that allows me to select the picture ...when i click on it the app crashes and gives me the following error: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
I have searched the internet for days and couldn't find a proper solution to this. I would appreciate it if anyone could find me a solution to this.
URI of the selected image is not returned in Intent extras, but in the data of intent. You can get the selected image's URI as follows.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data !=null) {
if (requestCode == REQUEST_IMAGE_CAPTURE || requestCode== IMAGE_PICK_CODE) {
// Get image URI From intent
var imageUri = data.data
// do something with the image URI
your_image_view.setImageURI(imageUri)
}
}
super.onActivityResult(requestCode, resultCode, data)
}
Related
I thank you in advance for your help. I am not a professional developer. I'm a teacher. I'm looking to create an app that can time student performance. I want to start a general stopwatch and stop the stopwatch individually. But, I encounter a problem either I don't have a crash but I can't interact on the individual stop button or I have a crash of type "binding.btnStop make not null"
Can you tell me how I can interact between the adapter and the fragment to link the general and individual timers and to stop the individual timer?
Thank you in advance for your help
Here is my code:
EvalFragment.class
var mDisplay: Display? = null
var path: String? = null
val REQUEST_CODE = 1
var isPlay = false
var pauseOffSet :Long = 0
//Test chrono millisec
var isResume = false
private lateinit var handler: Handler
var tMilliSec = 0L
var tStart = 0L
var tBuff = 0L
var tUpdate = 0L
var sec: Int = 0
var min: Int = 0
var milliSec: Int = 0
//Pour accéder au fab
private var _binding: FragmentEvalBinding? = null
private val binding get() = _binding!!
private lateinit var mUserViewModel: UserViewModel
private lateinit var mUserEvalViewModel: UserEvalViewModel
private val args by navArgs<EvalFragmentArgs>()
private lateinit var btPlay: ImageButton
private lateinit var btnPause: ImageButton
private lateinit var btStop: ImageButton
private lateinit var chronomter: Chronometer
#RequiresApi(Build.VERSION_CODES.R)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
_binding = FragmentEvalBinding.inflate(inflater, container, false)
val view = binding.root
//Recyclerview pour afficher le custom row et les données
val adapter = EvalAdapter()
val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerview_time)
recyclerView?.adapter = adapter
recyclerView?.layoutManager = LinearLayoutManager(requireContext())
mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
mUserEvalViewModel = ViewModelProvider(this).get(UserEvalViewModel::class.java)
chronomter = binding.chronometerGeneral
btPlay = binding.btStart
btStop = binding.btStop
btnPause = binding.btPause
handler = Handler()
btPlay.setOnClickListener {
if(!isResume){
tStart = SystemClock.uptimeMillis()
handler.postDelayed(runnable, 0)
chronomter.start()
binding.recyclerviewTime.chronometerIndividuel.start()
isResume = true
btStop.visibility = View.GONE
btPlay.setImageDrawable(resources.getDrawable(R.drawable.ic_pause))
} else {
tBuff += tMilliSec
handler.removeCallbacks(runnable)
chronomter.stop()
binding.recyclerviewTime.chronometerIndividuel.stop()
isResume = false
btStop.visibility = View.VISIBLE
btPlay.setImageDrawable(resources.getDrawable(R.drawable.ic_play))
}
}
btnPause.setOnClickListener {
pause()
}
btStop.setOnClickListener {
stop()
if(!isResume){
btPlay.setImageDrawable(resources.getDrawable(R.drawable.ic_play))
tMilliSec = 0L
tStart = 0L
tBuff = 0L
tUpdate = 0L
sec = 0
min = 0
milliSec = 0
chronomter.setText("00:00:00")
binding.recyclerviewTime.chronometerIndividuel.setText("00:00:00")
}
}
val userStart = args.currentUser.time
mUserEvalViewModel.readAllDataUserEval?.observe(viewLifecycleOwner, Observer { user ->
adapter.setDataEval(user)
})
val wm: WindowManager? =
activity?.getSystemService(Context.WINDOW_SERVICE) as WindowManager?
mDisplay = wm!!.defaultDisplay
if (ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
requireActivity(),
arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA,
), REQUEST_CODE
)
} else {
Toast.makeText(
requireContext(),
"Veuillez accepter les permissions",
Toast.LENGTH_SHORT
).show()
}
// Add menu
setHasOptionsMenu(true)
return view
}
val runnable: Runnable = object : Runnable {
override fun run() {
tMilliSec = SystemClock.uptimeMillis() - tStart
tUpdate = tBuff + tMilliSec
sec = (tUpdate/1000).toInt()
min= sec/60
sec = sec%60
milliSec = (tUpdate%100).toInt()
chronomter.setText(String.format("%02d", min)+":"
+ String.format("%02d", sec)+":"+String.format("%02d", milliSec))
handler.postDelayed(this, 60)
}
}
private fun clicSound() {
val mediaPlayer: MediaPlayer = MediaPlayer.create(context, R.raw.positive_notification)
mediaPlayer.start()
}
private fun pause() {
if (isPlay){
chronomter.stop()
pauseOffSet = SystemClock.elapsedRealtime() - chronomter.base
isPlay = false
btnPause.setBackgroundResource(R.drawable.ic_play)
Toast.makeText(context,"Chronomètre: en Pause !!",Toast.LENGTH_SHORT).show()
}
else{
chronomter.base = SystemClock.elapsedRealtime() - pauseOffSet
chronomter.start()
btnPause.setBackgroundResource(R.drawable.ic_pause)
Toast.makeText(context,"Chronomètre : en route !!",Toast.LENGTH_SHORT).show()
isPlay = true
}
}
private fun play() {
chronomter.base = SystemClock.elapsedRealtime() - pauseOffSet
chronomter.start()
btPlay.setBackgroundResource(R.drawable.ic_stop)
Toast.makeText(context,"Chronomètre déclenché !!",Toast.LENGTH_SHORT).show()
isPlay =true
}
private fun stop() {
chronomter.base = SystemClock.elapsedRealtime()
pauseOffSet = 0
chronomter.stop()
btPlay.setBackgroundResource(R.drawable.ic_play)
Toast.makeText(context, "Chronomètre arrêté !!", Toast.LENGTH_SHORT).show()
isPlay = false
}
private fun reset(){
chronomter.base = SystemClock.elapsedRealtime() - pauseOffSet
chronomter.stop()
btnPause.visibility = View.INVISIBLE
btPlay.setBackgroundResource(R.drawable.ic_play)
Toast.makeText(context,"Chronomter is Start !!",Toast.LENGTH_SHORT).show()
isPlay = false
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PackageManager.PERMISSION_GRANTED && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(requireContext(), "Permission Autorisée", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(requireContext(), "Permission Refusée", Toast.LENGTH_SHORT).show()
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.delete_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menu_delete) {
// deleteAllEvals()
}
return super.onOptionsItemSelected(item)
}
}```
My EvalAdapter.class:
```class EvalAdapter: RecyclerView.Adapter<EvalAdapter.MyViewHolder>() {
var evalList = emptyList<UserWithEval>()
private lateinit var mUserViewModel: UserViewModel
private lateinit var mEvalViewModel: EvalViewModel
private lateinit var mUserWithEvalViewModel: UserEvalViewModel
private lateinit var firstName: String
private lateinit var lastName: String
private var idUser: Int = 0
private var user_id_reference: Int = 0
private var gru_id_reference: Int = 0
private var timeInterDepart = 0
private lateinit var chronoInd : Chronometer
private lateinit var chronoGeneral : Chronometer
private lateinit var context: Context
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
context = parent.context
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.custom_time, parent, false)
)
}
override fun getItemCount(): Int {
return evalList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItemUser = evalList[position]
holder.itemView.findViewById<TextView>(R.id.firstName_txt).text = currentItemUser.firstName.uppercase()
holder.itemView.findViewById<TextView>(R.id.lastName_txt).text = currentItemUser.lastName.uppercase()
chronoInd = holder.itemView.findViewById(R.id.chronometerIndividuel)
holder.itemView.findViewById<Button>(R.id.bt_stop_individuel).setOnClickListener {
chronoInd.stop()
}
}
fun setDataEval(user: List<UserWithEval>){
this.evalList = user
notifyDataSetChanged()
}
}```
fragment_eval.xml:
```<?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="#drawable/gradient_background"
android:orientation="horizontal"
android:id="#+id/fragEval">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview_time"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/linearLayoutCompat"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_margin="30dp"
android:background="#drawable/bg_round"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Chronometer
android:id="#+id/chronometerGeneral"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format="00:00:00"
android:textColor="#color/white"
android:textSize="40sp"
android:textStyle="bold" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<ImageButton
android:id="#+id/bt_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/transparent_background"
android:src="#drawable/ic_play" />
<ImageButton
android:id="#+id/bt_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/transparent_background"
android:src="#drawable/ic_stop" />
<ImageButton
android:id="#+id/bt_pause"
android:visibility="invisible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/transparent_background"
android:src="#drawable/ic_pause" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<EditText
android:id="#+id/editTextTempsDepart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_input_eval"
android:drawableLeft="#drawable/ic_chrono"
android:hint=" 15 "
android:inputType="number"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="#+id/linearLayoutCompat"
app:layout_constraintEnd_toStartOf="#+id/linearLayoutCompat"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/validTempsDepart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/validate"
android:layout_marginLeft="20dp"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/editTextTempsDepart"
app:layout_constraintStart_toEndOf="#+id/editTextTempsDepart"
app:layout_constraintTop_toTopOf="#+id/editTextTempsDepart" />
<TextView
android:id="#+id/tvTempsPremierDepart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_input"
android:text="00 sec"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#+id/linearLayoutCompat"
app:layout_constraintTop_toBottomOf="#+id/linearLayoutCompat" />
</androidx.constraintlayout.widget.ConstraintLayout>
custom_time.xml:
<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="#drawable/gradient_background"
tools:context=".MainActivity">
//1ère ligne du chrono
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Button
android:id="#+id/bt_stop_individuel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:background="#drawable/shape_background"
android:text="#string/stop"
android:textColor="#color/white"
android:textSize="30sp"
android:textStyle="bold" />
<TextView
android:id="#+id/firstName_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="#string/firstName"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="#+id/lastName_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="#string/lastName"
android:textSize="25sp"
android:textStyle="bold" />
<Chronometer
android:id="#+id/chronometerIndividuel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:format="00:00:00"
android:text="00:00:00"
android:textSize="30sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I am trying to add UnifiedNative ads in my xamarin.forms Application. I successfully implemented them in Android but having a hard time for iOS.
For Android - I have created a custom renderer and a xml layout for holding the Ad content.
For ios, I tried to follow this - github.com/xamarin/GoogleApisForiOSComponents/blob/master/docs/Firebase/AdMob/ but it is not very clear and provides help only in Swift/Objective C and I am looking for C#.
EDIT -
Xamarin.Forms
in .xaml
<adview:AdmobNativeAd HeightRequest="360"></adview:AdmobNativeAd>
AdView class -
public class AdmobNativeAd : ContentView
{
public AdmobNativeAd()
{
this.HeightRequest = 360;
this.Margin = new Thickness(8, 8, 8, 0);
SetPlaceholderContent();
}
private void SetPlaceholderContent()
{
var placeholderGrid = new Grid();
var placeHolderText = new Label
{
Text = "AD",
FontSize = 48,
FontAttributes = FontAttributes.Bold,
TextColor = Color.White,
Opacity = 0.3,
VerticalOptions = new LayoutOptions(LayoutAlignment.Center, true),
HorizontalOptions = new LayoutOptions(LayoutAlignment.Center, true)
};
placeholderGrid.Children.Add(placeHolderText);
this.Content = placeholderGrid;
}
}
Android Implementation -
[assembly: ExportRenderer(typeof(AdmobNativeAd), typeof(xxx.Droid.Services.NativeAd))]
namespace xxx.Droid.Services
{
public class NativeAd : ViewRenderer
{
public NativeAd(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var adLoader = new AdLoader.Builder(Context, "ca-app-pub-xxxxxxxxxxx/xxxxxxxx");
var listener = new UnifiedNativeAdLoadedListener();
listener.OnNativeAdLoaded += (s, ad) =>
{
try
{
var root = new UnifiedNativeAdView(Context);
var inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
var adView = (UnifiedNativeAdView)inflater.Inflate(Resource.Layout.ad_unified, root);
populateUnifiedNativeAdView(ad, adView);
SetNativeControl(adView);
}
catch
{
}
};
adLoader.ForUnifiedNativeAd(listener);
var requestBuilder = new AdRequest.Builder();
adLoader.Build().LoadAd(requestBuilder.Build());
}
}
private void populateUnifiedNativeAdView(UnifiedNativeAd nativeAd, UnifiedNativeAdView adView)
{
adView.MediaView = adView.FindViewById<MediaView>(Resource.Id.ad_media);
// Set other ad assets.
adView.HeadlineView = adView.FindViewById<TextView>(Resource.Id.ad_headline);
adView.BodyView = adView.FindViewById<TextView>(Resource.Id.ad_body);
adView.CallToActionView = adView.FindViewById<TextView>(Resource.Id.ad_call_to_action);
adView.IconView = adView.FindViewById<ImageView>(Resource.Id.ad_app_icon);
adView.PriceView = adView.FindViewById<TextView>(Resource.Id.ad_price);
adView.StarRatingView = adView.FindViewById<RatingBar>(Resource.Id.ad_stars);
adView.StoreView = adView.FindViewById<TextView>(Resource.Id.ad_store);
adView.AdvertiserView = adView.FindViewById<TextView>(Resource.Id.ad_advertiser);
// The headline and mediaContent are guaranteed to be in every UnifiedNativeAd.
((TextView)adView.HeadlineView).Text = nativeAd.Headline;
// These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
// check before trying to display them.
if (nativeAd.Body == null)
{
adView.BodyView.Visibility = ViewStates.Invisible;
}
else
{
adView.BodyView.Visibility = ViewStates.Visible;
((TextView)adView.BodyView).Text = nativeAd.Body;
}
if (nativeAd.CallToAction == null)
{
adView.CallToActionView.Visibility = ViewStates.Invisible;
}
else
{
adView.CallToActionView.Visibility = ViewStates.Visible;
((Android.Widget.Button)adView.CallToActionView).Text = nativeAd.CallToAction;
}
if (nativeAd.Icon == null)
{
adView.IconView.Visibility = ViewStates.Gone;
}
else
{
((ImageView)adView.IconView).SetImageDrawable(nativeAd.Icon.Drawable);
adView.IconView.Visibility = ViewStates.Visible;
}
if (string.IsNullOrEmpty(nativeAd.Price))
{
adView.PriceView.Visibility = ViewStates.Gone;
}
else
{
adView.PriceView.Visibility = ViewStates.Visible;
((TextView)adView.PriceView).Text = nativeAd.Price;
}
if (nativeAd.Store == null)
{
adView.StoreView.Visibility = ViewStates.Invisible;
}
else
{
adView.StoreView.Visibility = ViewStates.Visible;
((TextView)adView.StoreView).Text = nativeAd.Store;
}
if (nativeAd.StarRating == null)
{
adView.StarRatingView.Visibility = ViewStates.Invisible;
}
else
{
((RatingBar)adView.StarRatingView).Rating = nativeAd.StarRating.FloatValue();
adView.StarRatingView.Visibility = ViewStates.Visible;
}
if (nativeAd.Advertiser == null)
{
adView.AdvertiserView.Visibility = ViewStates.Invisible;
}
else
{
((TextView)adView.AdvertiserView).Text = nativeAd.Advertiser;
adView.AdvertiserView.Visibility = ViewStates.Visible;
}
// This method tells the Google Mobile Ads SDK that you have finished populating your
// native ad view with this native ad.
adView.SetNativeAd(nativeAd);
}
}
public class UnifiedNativeAdLoadedListener : AdListener, UnifiedNativeAd.IOnUnifiedNativeAdLoadedListener
{
public void OnUnifiedNativeAdLoaded(UnifiedNativeAd ad)
{
OnNativeAdLoaded?.Invoke(this, ad);
}
public EventHandler<UnifiedNativeAd> OnNativeAdLoaded { get; set; }
}
}
XML to handle received Ad Content -
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.formats.UnifiedNativeAdView android:hardwareAccelerated="false"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardPreventCornerOverlap="false"
app:cardCornerRadius="12dp">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFFFFF">
<AbsoluteLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<com.google.android.gms.ads.formats.MediaView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/ad_media"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="Ad"
android:textColor="#FFFFFF"
android:background="#FFCC66"
android:textSize="14sp"
android:padding="4dp" />
</AbsoluteLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="fill_horizontal">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/ad_app_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:paddingBottom="5dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#0000FF"
android:text="Join the dark side!"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/ad_advertiser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textSize="14sp"
android:text="Google"
android:textColor="#222222"
android:textStyle="bold"/>
<RatingBar
android:id="#+id/ad_stars"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5"
android:rating="4" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:textColor="#555555"
android:id="#+id/ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nis."
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:paddingLeft="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:id="#+id/ad_store"
android:text="Google Play"
android:textColor="#222222"
android:textSize="12sp" />
<Button
android:id="#+id/ad_call_to_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="0dp"
android:text="INSTALL"
android:textSize="12sp" />
<TextView
android:id="#+id/ad_price"
android:text="$ 3.49"
android:textColor="#222222"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</com.google.android.gms.ads.formats.UnifiedNativeAdView>
I have referred this article for Android Implmentation -
https://startdebugging.net/2019/09/admob-native-ads-in-xamarin-forms-android/
I tried this in IOS and my code so far is this -
[assembly: ExportRenderer(typeof(AdmobNativeAd), typeof(AdMobNativeAdRenderer))]
namespace xxxx.iOS.Renderers
{
public class AdMobNativeAdRenderer : ViewRenderer<AdmobNativeAd, NativeExpressAdView>
{
NativeExpressAdView mAdView;
bool viewOnScreen;
// public AdMobNativeAdRenderer(Context context) : base() { }
protected override void OnElementChanged(ElementChangedEventArgs<AdmobNativeAd> e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
return;
if (e.OldElement == null)
{
CreateAdView(this);
}
}
private void CreateAdView(AdMobNativeAdRenderer renderer)
{
if (Element == null) return;
var loader = new AdLoader(
"ca-app-pub-xxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxx",
GetVisibleViewController(),
new AdLoaderAdType[] { AdLoaderAdType.UnifiedNative },
new AdLoaderOptions[] {
new NativeAdViewAdOptions {PreferredAdChoicesPosition = AdChoicesPosition.TopRightCorner}
});
var request = Request.GetDefaultRequest();
request.TestDevices = new string[] { Request.SimulatorId };
if (adView == null) return;
try
{
loader.Delegate = new MyAdLoaderDelegate(renderer);
loader.LoadRequest(request);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
Debug.WriteLine("Loading: " + loader.IsLoading);
}
private UIViewController GetVisibleViewController()
{
var windows = UIApplication.SharedApplication.Windows;
foreach (var window in windows)
{
if (window.RootViewController != null)
{
return window.RootViewController;
}
}
return null;
}
I couldn't figure out how to create UI similar to xml doc above for IOS and link it with the delegate.
Also, I would like to mention I am using Visual studio 2019 Windows for this project.
I am trying to display notes in my recycler view. the note body is like this:
Note Title in one text view
Note Content in the other text view below the title
So, this will get displayed in one Item and then the next note in the next item. But the issue is that,
one item is containing the note title, and the other one is containing its content.
Here is my NotesAdapter Class:
class NotesAdapter(private var noteView: ArrayList<String>):
RecyclerView.Adapter<NotesAdapter.MyViewHolder>() {
inner class MyViewHolder(noteView: View) : RecyclerView.ViewHolder(noteView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val noteView : View =LayoutInflater.from(parent.context).inflate(R.layout.note_card,parent,false)
return MyViewHolder(noteView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
//Set data here
holder.itemView.apply {
note_title_TV.text = noteView[position]
note_content_TV.text = noteView[position]
}
}
override fun getItemCount(): Int {
return noteView.size
}
}
My Main Activity Class (This class contains my firebase code too, as I am reading data from there and storing that into a list) :
class HomeActivity : AppCompatActivity() {
var nList = ArrayList<String>();
private lateinit var recyclerView: RecyclerView
private lateinit var viewAdapter: RecyclerView.Adapter<*>
private lateinit var viewManager: RecyclerView.LayoutManager
val rootReference = Firebase.database.reference //app root in firebase database
val currentUser = FirebaseAuth.getInstance().currentUser
val uid = currentUser?.uid.toString()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
//Show user's name in welcome message
//get the name of user from firebase
val nameFromFirebase: FirebaseDatabase = FirebaseDatabase.getInstance()
var nameReference = rootReference.child("users").child(uid).child("name")
nameReference.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val result = snapshot.value
tv_User_Name.text = result.toString()
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
btn_createNote.setOnClickListener {
Intent(this, AddNoteActivity::class.java).also {
startActivity(it)
}
}
//Read notes from database
readNotesFromFirebaseDatabase()
//Updating Layout to display notes in RecyclerView
recyclerView = findViewById<RecyclerView>(R.id.rv_displayNotesInRecyclerView)
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager=LinearLayoutManager(this)
//RecyclerView Adapter being passed the notes list
val adapter = NotesAdapter(nList)
rv_displayNotesInRecyclerView.adapter = adapter
}
fun readNotesFromFirebaseDatabase(){
val noteReference = rootReference.child("users").child(uid).child("Notes")
noteReference.addValueEventListener(object:ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
val noteContent = snapshot.child("noteContent").getValue(String::class.java)
val noteTitle = snapshot.child("noteTitle").getValue(String::class.java)
//Add Notes to the ArrayList of Notes
nList.add(noteTitle.toString())
nList.add(noteContent.toString())
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
}
Note_item XML Layout File:
<?xml version="1.0" encoding="UTF-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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="wrap_content">
<androidx.cardview.widget.CardView
android:id="#+id/prompt_cardview"
android:layout_width="390dp"
android:layout_height="89dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:minHeight="120dp"
app:cardCornerRadius="15dp"
app:cardElevation="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="384dp"
android:layout_height="match_parent"
android:minHeight="120dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/note_title_TV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:fontFamily="#font/lato"
android:lineHeight="22dp"
android:text="Title"
android:textAlignment="gravity"
android:textColor="#4F4B4B"
android:textSize="18sp"
android:textStyle="bold"
android:paddingLeft="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.037"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/note_content_TV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginStart="12dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="8dp"
android:fontFamily="#font/lato"
android:paddingLeft="5dp"
android:lineHeight="14dp"
android:singleLine="false"
android:text="#string/some_comments_are_here_to_stay_you_know"
android:textAlignment="center"
android:textColor=" #877B7B"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/note_title_TV"
app:layout_constraintVertical_bias="0.0" />
<ImageButton
android:id="#+id/btn_edit"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="#drawable/round_button_edit"
android:src="#drawable/icon_btn_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btn_delete"
app:layout_constraintHorizontal_bias="0.972"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/note_content_TV"
app:layout_constraintVertical_bias="1.0" />
<ImageButton
android:id="#+id/btn_delete"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="#drawable/round_button_delete"
android:src="#drawable/icon_btn_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.983"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/note_content_TV"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I Also have made a Note Class (if it may be of any assistance) :
class Note (val noteContent:String , val noteTitle: String) {
}
This is my Firebase Database Note Entry, 1:https://i.stack.imgur.com/bixCW.png
Now, I am getting this output, 2: https://i.stack.imgur.com/VV7l7.png
P.S I know there are some posts regarding this like this one: How to create Multiple View Type in Recycler View but they are in Java and I am getting stuck while converting that here.
Try this:
Create a model class with 2 variables
class Notes{
val title: String = ""
val content: String = ""
}
after that creates an array list using that model class instead of String which looks like this:
val list: MutableList<Notes> = Notes()
val nots : Notes = Notes()
notes.title = "test"
notes.content = "Good Work!"
list.add(notes)
Once your list is created pass that list to adapter and you are good to go
class NotesAdapter(private var list: ArrayList<Note>):
RecyclerView.Adapter<NotesAdapter.MyViewHolder>() {
inner class MyViewHolder(noteView: View) : RecyclerView.ViewHolder(noteView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val noteView : View = LayoutInflater.from(parent.context).inflate(R.layout.note_card,parent,false)
return MyViewHolder(noteView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.itemView.apply {
note_title_TV.text = list[position].title
note_content_TV.text = list[position].content
}
}
override fun getItemCount(): Int {
return list.size
}
}
The problem is solved.
Change the ArrayList from String to Note
And in the Main Activity Class, edited this block of code:
//Add Notes to the ArrayList of Notes
var note : Note
note.noteContent = noteTitle.toString()
note.noteTitle = noteTitle.toString()
In the NotesAdapter Class (Posting the complete correct code):
class NotesAdapter(private var noteView: ArrayList<Note>):
RecyclerView.Adapter<NotesAdapter.MyViewHolder>() {
inner class MyViewHolder(noteView: View) : RecyclerView.ViewHolder(noteView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val noteView : View = LayoutInflater.from(parent.context).inflate(R.layout.note_card,parent,false)
return MyViewHolder(noteView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
//Set data here
holder.itemView.apply {
note_title_TV.text = noteView[position].noteContent
note_content_TV.text = noteView[position].noteTitle
}
}
override fun getItemCount(): Int {
return noteView.size
}
}
I am trying to display a dialog on Android using Dependency Service. However, I could not get the design I create in android layout designer to display, the result comes out is different.
This is the screenshot of my previewer:
Expected design
This is the screenshot of my result:
Unexpected result
My axml code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dialogWrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:background="#drawable/backgroundstyle"
android:layout_marginRight="16dp"
android:stateListAnimator="#null">
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="16dp"
android:textAlignment="center"
android:textColor="#000"
android:textSize="19sp"
android:text="TitleText"
android:textStyle="bold" />
<TextView
android:id="#+id/subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/title"
android:paddingBottom="16dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="4dp"
android:textAlignment="center"
android:text="subtitle test"
android:textColor="#000"
android:textSize="15sp" />
<RelativeLayout
android:id="#+id/RL_editTextWrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/subtitle"
android:padding="15dp"
>
<EditText
android:id="#+id/inputText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/roundedentry"
android:paddingBottom="8dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="8dp"
android:textAlignment="center"
android:textColor="#000"
android:text="inputText test"
android:textSize="15sp" />
</RelativeLayout>
<View
android:id="#+id/line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="#+id/RL_editTextWrapper"
android:background="#cdced2" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/line"
android:orientation="horizontal">
<TextView
android:id="#+id/dialogButtonNO"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:stateListAnimator="#null"
android:textAlignment="center"
android:textColor="#007aff"
android:text="Cancel"
android:textSize="19sp" />
<View
android:id="#+id/separator"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#cdced2" />
<TextView
android:id="#+id/dialogButtonOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:stateListAnimator="#null"
android:textAlignment="center"
android:textColor="#007aff"
android:textSize="19sp"
android:text="Ok"
android:textStyle="bold" />
</LinearLayout>
The #drawable/backgroundstyle code:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#android:color/white"/>
<corners
android:radius="16dp" />
This is the code for exporting dependency service in android:
namespace FFF.Droid.Native {
public class IOSDialogStyleDroid : IIOSDialogStyle {
public void ShowPopup(EntryPopup entryPopup) {
var context = CrossCurrentActivity.Current.Activity as FormsAppCompatActivity;
CustomDialog customDialog = new CustomDialog(context) {
entryPopup = entryPopup
};
customDialog.Show();
}
}
public class CustomDialog : Dialog {
public Context context { get; set; }
public EntryPopup entryPopup { get; set; }
public CustomDialog(Context context) : base(context) {
this.context = context;
}
protected override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
RequestWindowFeature((int)WindowFeatures.NoTitle);
SetContentView(Resource.Layout.iOSStyleDialog);
EditText editText = FindViewById(Resource.Id.inputText) as EditText;
(FindViewById(Resource.Id.title) as TextView).Text = entryPopup.Title;
(FindViewById(Resource.Id.subtitle) as TextView).Text = entryPopup.Message;
var btnOk = FindViewById(Resource.Id.dialogButtonOK) as TextView;
btnOk.Text = entryPopup.okButton;
btnOk.Click += (object sender, EventArgs e) => {
entryPopup.OnPopupClosed(new EntryPopupClosedArgs {
Button = entryPopup.okButton,
Text = editText.Text
});
Dismiss();
};
var btnNo = FindViewById(Resource.Id.dialogButtonNO) as TextView;
btnNo.Text = entryPopup.cancelButton;
btnNo.Click += (object sender, EventArgs e) => {
entryPopup.OnPopupClosed(new EntryPopupClosedArgs {
Button = entryPopup.cancelButton,
Text = editText.Text
});
Dismiss();
};
}
}
I found out that textalignment seems broken, I use gravity instead.
Greeting
When I click on the camera text, the app shows an error said "The application has stopped". How it can be fixed?
MaingActivity.java
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
CameraFragment cameraFragment = new CameraFragment();
FragmentManager manager= getSupportFragmentManager();
manager.beginTransaction().replace(
R.id.relativelayout_for_fragment,
cameraFragment,
cameraFragment.getTag()
).commit();
} else if (id == R.id.nav_gallery) {
Toast.makeText(this,"Gallary",Toast.LENGTH_SHORT).show();
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
I have found it
Select contant_main.xml => click on icon refer Constrains
The code will be as the following
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.shakeralmoosa.nav1.MainActivity"
tools:showIn="#layout/app_bar_main"
android:id="#+id/mainLayout">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="0dp"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
android:layout_marginStart="5dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="5dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="4dp"
tools:layout_constraintLeft_creator="1"
android:layout_marginBottom="4dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
</RelativeLayout>
</android.support.constraint.ConstraintLayout>