Tag: Learn android
em kotlin: gps terceira versão com mapa
Adicionar uma dependência via menus no build-gradle (module)
(1)
ficheiro: build-gradle(module)
... dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.google.android.gms:play-services-location:17.1.0' implementation 'com.google.android.gms:play-services-maps:17.0.0' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.isec.estuda.amov_gpsv1"> <!-- pedir estas permissões --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- pedir estas permissões para aceder aos mapas e ao estado da rede não são em runtime --> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Amov_gpsv1"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyD4M076vcUKcPZNGlyBzFshU-J4jJ98x5g"/> </application> </manifest>
ficheiro: MainActivity.kt
package pt.isec.estuda.amov_gpsv1 import android.Manifest import android.annotation.SuppressLint import android.content.pm.PackageManager import android.graphics.Color import android.location.Location import android.location.LocationListener import android.location.LocationManager import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import androidx.core.app.ActivityCompat import com.google.android.gms.location.* import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.CameraPosition import com.google.android.gms.maps.model.CircleOptions import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions const val TAG = "Location" class MainActivity : AppCompatActivity(), OnMapReadyCallback{ var locEnable = false //caso não ajam permissões lateinit var fLoc : FusedLocationProviderClient val ISEC = LatLng(40.1925, -8.4115) val DEIS = LatLng(40.1925, -8.4128) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) fLoc = FusedLocationProviderClient(this) //pedir o objeto google maps e vai ser necessário o OnMapReadyCallback (supportFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment)?.getMapAsync(this) } override fun onResume() { super.onResume() startLocationServices(true) //para poupanças de energia, ativar o mais tarde possivel } override fun onPause() { super.onPause() //para poupanças de energia, desactivar o mais cedo possivel if(locEnable) { locEnable = false } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) //se tivermos as permissões //locationM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 100f, this) if(requestCode == 1289) { startLocationServices(false) } } fun startLocationServices(askPerm : Boolean) { //1ºprovider, 2º intervalo de segundos,3º distancia minima ,4º o listener //se for for telemovel NETWORK_PROVIDER //dar permissões: ACCESS_FINE_LOCATION //e pedir em runtime, add permissions check if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { //pedir as permissões //&& ou || if (askPerm) { ActivityCompat.requestPermissions(this, arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), 1289) //1289 um valor qualquer! } else { finish() } return } val locRequest = LocationRequest().apply { interval = 4000 priority = LocationRequest.PRIORITY_HIGH_ACCURACY //ocultar para ja estes dois: //fastestInterval = 2000 //maxWaitTime = 10000 //numUpdates /? a ver, quantidade de updates } //activar locEnable = true fLoc.requestLocationUpdates(locRequest, locationCallBack, null) } //função locationCallBack var locationCallBack = object : LocationCallback() { override fun onLocationResult(p0: LocationResult?) { Log.i(TAG, "onLocationAvailability: ") //locations é uma lista de localizações p0?.locations?.forEach { Log.i(TAG, "onLocationAvailability: ${it.latitude} ${it.longitude}") } } } @SuppressLint("MissingPermission") override fun onMapReady(map: GoogleMap?) { //implementar o omMapReady, sendo p0 o ojecto google maps map ?: return //if map == null return map.isMyLocationEnabled = true map.uiSettings.isCompassEnabled = true map.uiSettings.isZoomControlsEnabled = true map.uiSettings.isZoomGesturesEnabled = true val cp = CameraPosition.Builder().target(ISEC).zoom(17f).bearing(0f).tilt(0f).build() map.animateCamera(CameraUpdateFactory.newCameraPosition(cp)) map.addCircle( CircleOptions().center(ISEC).radius(150.0).fillColor(Color.argb(128,128,128,128)).strokeColor(Color.rgb(128,0,0)).strokeWidth(4f) ) val mo = MarkerOptions().position(ISEC).title("ISEC-IPC").snippet("Instituo.....") val isec = map.addMarker(mo) isec.showInfoWindow() map.addMarker(MarkerOptions().position(DEIS).title("DEIS-ISEC")) } }
ficheiro: activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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"> <!-- incluimos o mapa como um fragmento --> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.SupportMapFragment"/> </FrameLayout>
em kotlin: gps segunda versão
Adicionar uma dependência via menus no build-gradle (module)
(1)
(2)
(3)
ficheiro: build-gradle(module)
... dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.google.android.gms:play-services-location:17.1.0' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.isec.estuda.amov_gpsv1"> <!-- pedir estas permissões --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Amov_gpsv1"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: MainActivity.kt
package pt.isec.estuda.amov_gpsv1 import android.Manifest import android.content.pm.PackageManager import android.location.Location import android.location.LocationListener import android.location.LocationManager import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import androidx.core.app.ActivityCompat import com.google.android.gms.location.* const val TAG = "Location" class MainActivity : AppCompatActivity() { var locEnable = false //caso não ajam permissões lateinit var fLoc : FusedLocationProviderClient override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) fLoc = FusedLocationProviderClient(this) } override fun onResume() { super.onResume() startLocationServices(true) //para poupanças de energia, ativar o mais tarde possivel } override fun onPause() { super.onPause() //para poupanças de energia, desactivar o mais cedo possivel if(locEnable) { locEnable = false } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) //se tivermos as permissões //locationM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 100f, this) if(requestCode == 1289) { startLocationServices(false) } } fun startLocationServices(askPerm : Boolean) { //1ºprovider, 2º intervalo de segundos,3º distancia minima ,4º o listener //se for for telemovel NETWORK_PROVIDER //dar permissões: ACCESS_FINE_LOCATION //e pedir em runtime, add permissions check if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { //pedir as permissões //&& ou || if (askPerm) { ActivityCompat.requestPermissions(this, arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), 1289) //1289 um valor qualquer! } else { finish() } return } val locRequest = LocationRequest().apply { interval = 4000 priority = LocationRequest.PRIORITY_HIGH_ACCURACY //ocultar para ja estes dois: //fastestInterval = 2000 //maxWaitTime = 10000 //numUpdates /? a ver, quantidade de updates } //activar locEnable = true fLoc.requestLocationUpdates(locRequest, locationCallBack, null) } } //função locationCallBack var locationCallBack = object : LocationCallback() { override fun onLocationResult(p0: LocationResult?) { Log.i(TAG, "onLocationAvailability: ") //locations é uma lista de localizações p0?.locations?.forEach { Log.i(TAG, "onLocationAvailability: ${it.latitude} ${it.longitude}") } } }
Com esta versão são feitos updates mais rapidamente, com a ajuda do LocationRequest.PRIORITY_HIGH_ACCURACY
este é o método recomendado pela google..
em kotlin: gps primeira versão
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.isec.estuda.amov_gpsv1"> <!-- pedir estas permissões --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Amov_gpsv1"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: MainActivity.kt
package pt.isec.estuda.amov_gpsv1 import android.Manifest import android.content.pm.PackageManager import android.location.Location import android.location.LocationListener import android.location.LocationManager import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import androidx.core.app.ActivityCompat const val TAG = "Location" class MainActivity : AppCompatActivity(), LocationListener { lateinit var locationM : LocationManager var locEnable = false //caso não ajam permissões override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) locationM = getSystemService(LOCATION_SERVICE) as LocationManager } override fun onResume() { super.onResume() startLocationServices(true) //para poupanças de energia, ativar o mais tarde possivel } override fun onPause() { super.onPause() //para poupanças de energia, desactivar o mais cedo possivel if(locEnable) { locationM.removeUpdates(this) locEnable = false } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) //se tivermos as permissões //locationM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 100f, this) if(requestCode == 1289) { startLocationServices(false) } } fun startLocationServices(askPerm : Boolean){ //1ºprovider, 2º intervalo de segundos,3º distancia minima ,4º o listener //se for for telemovel NETWORK_PROVIDER //dar permissões: ACCESS_FINE_LOCATION //e pedir em runtime, add permissions check if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { //pedir as permissões //&& ou || if(askPerm) { ActivityCompat.requestPermissions(this, arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), 1289) //1289 um valor qualquer! }else{ finish() } return } locationM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 100f, this) locEnable = true //outras: //addProximityAlert, funções de proximidade para um determinado local //addNmeaListener, ir buscar as mensagens de baixo nivel que um chip gps consegue obter //requestSingleUpdate, ir buscar apenas um update(uma localização armazenada) //getLastKnownLocation, obter um objeto Location, obtemos logo uma localização mesmo que não seja correta //providers, acerca dos requisitos da rede } override fun onLocationChanged(location: Location) { val latitude = location.latitude val longitude = location.longitude Log.i(TAG, "onLocationChanged: $latitude $longitude") //a ver o location.distanceTo() } }
em kotlin: uma recyclerView
ficheiro: MainActivity.kt
package pt.deis.estuda.estudoslistview2 import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun onRecyclerView(view: View) { val intent = Intent(this,RecyclerViewActivity::class.java) startActivity(intent) } }
ficheiro: activity_main.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" tools:context=".MainActivity"> <Button android:onClick="onRecyclerView" android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:text="recycler view" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ficheiro: activity_recycler_view.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" app:cardCornerRadius="6dp" app:cardElevation="6dp" android:layout_margin="6dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:textStyle="bold" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:id="@+id/recyclerTV1" android:textSize="24sp" android:text="Text 1" /> <TextView android:background="#f0f0f0" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:id="@+id/recyclerTV2" android:textSize="20sp" android:text="Text 2" /> <TextView android:background="#808080" android:textColor="#ffffff" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:id="@+id/recyclerTV3" android:textSize="16sp" android:text="Text 3" /> </LinearLayout> </androidx.cardview.widget.CardView>
ficheiro: activity_main.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" tools:context=".RecyclerViewActivity" android:padding="16dp"> <androidx.recyclerview.widget.RecyclerView android:padding="4dp" android:id="@+id/recyclerviewList" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.deis.estdua.arecyclerview"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.ARecyclerView"> <activity android:name=".RecyclerViewActivity" android:label="ListView" android:parentActivityName=".MainActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: RecyclerViewActivity.kt
package pt.deis.estuda.arecyclerview import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.StaggeredGridLayoutManager import kotlinx.android.synthetic.main.activity_recycler_view.* import kotlin.random.Random class RecyclerViewActivity : AppCompatActivity() { data class Dados(val str1:String,val str2 : String, val str3:String) val data = arrayListOf<Dados>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_recycler_view) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.subtitle = "Exemplo Recycler View" //sorterar numeros aleatoriamente repeat(Random.nextInt(10,20)) { val item = Dados("Titulo ${Random.nextInt(0,1000)}",getStr(50,400),getStr(5,20)) data.add(item) } //atribuir um layoutManager, um gestor para organizar os objectos, existem assim 3 tipos //LinearLayoutManager ou GridLayoutManager ou StaggeredGridLayoutManager //LinearLayoutManager.VERTICA - > lista com scroll na vertical //recyclerviewList.layoutManager = LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false) //recyclerviewList.layoutManager = GridLayoutManager(this,2,GridLayoutManager.VERTICAL,false) recyclerviewList.layoutManager = StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL) //MyRVAdapter derivado do RecyclerView.Adapter recyclerviewList.adapter = MyRVAdapter(data) } fun getStr(minc:Int,maxc: Int) : String { var str = "" val nrc = Random.nextInt(minc,maxc) repeat(nrc) { str += Random.nextInt(65,90).toChar() } return str } //é obrigatório o objecto ViewHolder, que representa cada um dos itens que vai ser visualizado class MyRVAdapter(val data : ArrayList<Dados>) : RecyclerView.Adapter<MyRVAdapter.MyViewHolder>() { class MyViewHolder(view : View) : RecyclerView.ViewHolder(view) { var tv1 : TextView = view.findViewById(R.id.recyclerTV1) var tv2 : TextView = view.findViewById(R.id.recyclerTV2) var tv3 : TextView = view.findViewById(R.id.recyclerTV3) //não é necessário.. e o update vai ser chamado pelo onBindViewHolder fun update(str1:String,str2:String,str3:String) { tv1.text = str1 tv2.text = str2 tv3.text = str3 } } //criar as vistas override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item ,parent,false) //e é retornado no contexto do MyViewHolder return MyViewHolder(view) } //inflate de um layout override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.update(data[position].str1,data[position].str2,data[position].str3) } //método para saber quantos elementos tem a lista override fun getItemCount(): Int = data.size } }
ficheiro: build.gralde (Module)
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // obrigatorio para aceder aos diferentes layouts sem usar o findId } ...
em kotlin: uma ListView XML array adapter personalizada v4 (destaque)
ficheiro: MainActivity.kt
package pt.deis.estuda.estudoslistview2 import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View const val TAG = "ListView" class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun onList4View(view: View) { val intent = Intent(this,ListView4Activity::class.java) startActivity(intent) } }
ficheiro: activity_main.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" tools:context=".MainActivity"> <Button android:onClick="onList4View" android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:text="ListView XML array adapter personalizado v4" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ficheiro: activity_list4_view.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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=".ListView4Activity"> <ListView android:id="@+id/quartaListView" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
ficheiro: arrays.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="dados_str"> <item>Portugal</item> <item>Espanha</item> <item>Franca</item> <item>Italia</item> <item>Alemanha</item> <item>Belgica</item> <item>Holanda</item> <item>Austria</item> <item>Luxemburgo</item> <item>Suecia</item> <item>Dinamarca</item> <item>Irlanda</item> <item>Croacia</item> <item>Eslovenia</item> <item>Eslovaquia</item> <item>Estonia</item> <item>Polonia</item> <item>Grecia</item> <item>Finlandia</item> <item>Chipre</item> <item>Malta</item> <item>Bulgaria</item> <item>Hungria</item> <item>Romenia</item> <item>Rep. Checa</item> <item>Letonia</item> <item>Lituania</item> </string-array> </resources>
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.deis.estuda.estudoslistview4"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Estudoslistview4"> <activity android:name=".ListView4Activity" android:label="ListView" android:parentActivityName=".MainActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: ListView4Activity.kt
package pt.deis.estuda.estudolistview4 import android.graphics.Color import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.ImageView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_list4_view.* import kotlin.random.Random class ListView4Activity : AppCompatActivity() { data class Pais (val nome : String, var habitantes:Int) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_list4_view) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.subtitle = "Exemplo 4" val paises = resources.getStringArray(R.array.dados_str) paises.sort() val data = arrayListOf<Pais>() for(p in paises) { val item = Pais(p, Random.nextInt(100000,99000000)) data.add(item) } val adapter = MyAdapter(data) quartaListView.adapter = adapter quartaListView.setOnItemClickListener() { parent, view, pos, id -> Log.i(TAG, "Item: $pos $id") } } //adapter personalizado derivado do BaseAdapter class MyAdapter(val data : ArrayList<Pais>) : BaseAdapter() { val imgs = arrayOf( android.R.drawable.ic_menu_agenda, android.R.drawable.ic_menu_camera, android.R.drawable.ic_menu_call, android.R.drawable.ic_menu_compass ) //sendo MyAdapater abstracta tenho que implementar os 4 próximos métodos //método devolve quantos items (usar do construtor do data) override fun getCount(): Int = data.size //método retorna o elemento de dados que está numa posição override fun getItem(position: Int): Any { return data[position] } //método para uma posição indica override fun getItemId(position: Int): Long = position.toLong() //metodo para retornar uma view, é um layout com tudo preenchido com o que queremos //o elemento neste caso é o position override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { //fazer o inflate do listview_item val view = LayoutInflater.from(parent!!.context).inflate(R.layout.listview4_item, parent, false) //para preencher os campos view.findViewById<TextView>(R.id.tv1).text = data[position].nome //usar o tv1 e tv2 para inserir os dados view.findViewById<TextView>(R.id.tv2).apply { text = data[position].habitantes.toString() //filtro dos dados dependendo das cores if (data[position].habitantes > 80000000) { setBackgroundColor(Color.rgb(128, 0, 0)) setTextColor(Color.WHITE) } //para reduzir o numero de abitantes quanto se dá um toque setOnClickListener { data[position].habitantes = (data[position].habitantes * 0.5).toInt() this@MyAdapter.notifyDataSetChanged() } //quando se faz o long click reponho o numero de habitantes setOnLongClickListener { data[position].habitantes = 99_000_000 this@MyAdapter.notifyDataSetChanged() true } } //associo uma imagem, sorteadas view.findViewById<ImageView>(R.id.ivImg) .setImageResource(imgs[Random.nextInt(imgs.size)]) return view } } }
ficheiro: listview4_item.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="4dp" android:background="#800000"> <ImageView android:id="@+id/ivImg" android:src="@android:drawable/ic_dialog_map" android:layout_width="32dp" android:layout_height="32dp" /> <TextView android:textStyle="bold" android:padding="4dp" android:textSize="20sp" android:text="text1" android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content" android:id="@+id/tv1" android:textColor="#000000" android:background="#f0d080"/> <TextView android:padding="4dp" android:textSize="20sp" android:gravity="right" android:text="text2" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/tv2" android:background="#80d0f0"/> </LinearLayout> </FrameLayout>
ficheiro: build.gralde (Module)
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // obrigatorio para aceder aos diferentes layouts sem usar o findId } ...
em kotlin: uma ListView XML array adapter personalizada v2 (numeros)
ficheiro: MainActivity.kt
package pt.deis.estuda.estudoslistview2 import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View const val TAG = "ListView" class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun onList2View(view: View) { val intent = Intent(this,ListView3Activity::class.java) startActivity(intent) } }
ficheiro: activity_main.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" tools:context=".MainActivity"> <Button android:onClick="onList2View" android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:text="ListView XML array adapter personalizado v2" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ficheiro: activity_list3_view.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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=".ListView3Activity"> <ListView android:id="@+id/terceiraListView" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
ficheiro: arrays.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="dados_str"> <item>Portugal</item> <item>Espanha</item> <item>Franca</item> <item>Italia</item> <item>Alemanha</item> <item>Belgica</item> <item>Holanda</item> <item>Austria</item> <item>Luxemburgo</item> <item>Suecia</item> <item>Dinamarca</item> <item>Irlanda</item> <item>Croacia</item> <item>Eslovenia</item> <item>Eslovaquia</item> <item>Estonia</item> <item>Polonia</item> <item>Grecia</item> <item>Finlandia</item> <item>Chipre</item> <item>Malta</item> <item>Bulgaria</item> <item>Hungria</item> <item>Romenia</item> <item>Rep. Checa</item> <item>Letonia</item> <item>Lituania</item> </string-array> </resources>
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.deis.estuda.estudoslistview3"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Estudoslistview3"> <activity android:name=".ListView3Activity" android:label="ListView" android:parentActivityName=".MainActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: ListView3Activity.kt
package pt.deis.estuda.estudolistview3 import android.os.Bundle import android.util.Log import android.widget.SimpleAdapter import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_list3_view.* import kotlin.random.Random class ListView3Activity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_list3_view) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.subtitle = "Exemplo 3" val paises = resources.getStringArray(R.array.dados_str) paises.sort() /* val data1 = mapOf("valor1" to 10, "valor2" to 20) val data2 = mapOf("valor1" to 11, "valor2" to 21) val data = mutableListOf(data1,data2) */ val data = mutableListOf<Map<String,Any>>() //Any() para ser qualquer tipo de dados //val i = Random.nextInt(10,20) for(p in paises) { val item = mapOf<String,Any>("valor1" to p, "valor2" to Random.nextInt(100000,99000000), "imagem" to android.R.drawable.ic_menu_compass) data.add(item) } val adapter = SimpleAdapter(this, data, R.layout.listview3_item, arrayOf("valor1","valor2","imagem"), intArrayOf(R.id.tv1, R.id.tv2, R.id.ivImg) ) //tv1 (recebe valor1), tv2 (recebe valor2)... dados das linhas terceiraListView.adapter = adapter terceiraListView.setOnItemClickListener() { parent, view, pos, id -> Log.i(TAG, "Item: $pos $id") } } }
ficheiro: listview3_item.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="4dp" android:background="#800000"> <ImageView android:id="@+id/ivImg" android:src="@android:drawable/ic_dialog_map" android:layout_width="32dp" android:layout_height="32dp" /> <TextView android:textStyle="bold" android:padding="4dp" android:textSize="20sp" android:text="text1" android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content" android:id="@+id/tv1" android:textColor="#000000" android:background="#f0d080"/> <TextView android:padding="4dp" android:textSize="20sp" android:gravity="right" android:text="text2" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/tv2" android:background="#80d0f0"/> </LinearLayout> </FrameLayout>
ficheiro: build.gralde (Module)
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // obrigatorio para aceder aos diferentes layouts sem usar o findId } ...
em kotlin: uma ListView XML array adapter personalizada
ficheiro: MainActivity.kt
package pt.deis.estuda.estudoslistview2 import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View const val TAG = "ListView" class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun onList2View(view: View) { val intent = Intent(this,ListView2Activity::class.java) startActivity(intent) } }
ficheiro: activity_main.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" tools:context=".MainActivity"> <Button android:onClick="onList2View" android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:text="ListView XML array adapter personalizado" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ficheiro: activity_list2_view.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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=".ListView2Activity"> <ListView android:id="@+id/segundaListView" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
ficheiro: arrays.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="dados_str"> <item>Portugal</item> <item>Espanha</item> <item>Franca</item> <item>Italia</item> <item>Alemanha</item> <item>Belgica</item> <item>Holanda</item> <item>Austria</item> <item>Luxemburgo</item> <item>Suecia</item> <item>Dinamarca</item> <item>Irlanda</item> <item>Croacia</item> <item>Eslovenia</item> <item>Eslovaquia</item> <item>Estonia</item> <item>Polonia</item> <item>Grecia</item> <item>Finlandia</item> <item>Chipre</item> <item>Malta</item> <item>Bulgaria</item> <item>Hungria</item> <item>Romenia</item> <item>Rep. Checa</item> <item>Letonia</item> <item>Lituania</item> </string-array> </resources>
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.deis.estuda.estudoslistview2"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Estudoslistview2"> <activity android:name=".ListView2Activity" android:label="ListView" android:parentActivityName=".MainActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: ListView2Activity.kt
package pt.deis.estuda.estudolistview import android.os.Bundle import android.util.Log import android.widget.ArrayAdapter import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_list2_view.* class ListView2Activity : AppCompatActivity() { var flag = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_list2_view) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.subtitle = "Exemplo 2" val paises = resources.getStringArray(R.array.dados_str) paises.sort() //id do elemento das strings ->,R.id.tv1 val adapter1 = ArrayAdapter<String>(this,R.layout.listview2_item,R.id.tv1,paises) //a segunda caixa de texto -> R.id.tv2 val adapter2 = ArrayAdapter<String>(this,R.layout.listview2_item,R.id.tv2,paises) segundaListView.adapter = adapter1 segundaListView.setOnItemClickListener() { parent, view, pos, id -> Log.i(TAG, "Item: $pos $id") //adapter1.notifyDataSetChanged() //serve para forçar o actualizar os dados segundaListView.adapter = if (flag) adapter1 else adapter2 flag = !flag } } }
ficheiro: listview2_item.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="4dp" android:background="#800000"> <ImageView android:id="@+id/ivImg" android:src="@android:drawable/ic_dialog_map" android:layout_width="32dp" android:layout_height="32dp" /> <TextView android:textStyle="bold" android:padding="4dp" android:textSize="20sp" android:text="text1" android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content" android:id="@+id/tv1" android:textColor="#000000" android:background="#f0d080"/> <TextView android:padding="4dp" android:textSize="20sp" android:gravity="right" android:text="text2" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/tv2" android:background="#80d0f0"/> </LinearLayout> </FrameLayout>
ficheiro: build.gralde (Module)
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // obrigatorio para aceder aos diferentes layouts sem usar o findId } ...
em kotlin: uma ListView XML array adapter
ficheiro: MainActivity.kt
package pt.deis.estuda.estudolistview import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View const val TAG = "ListView" class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } //nvoas actividades para fun onListView1(view: View) { val intent = Intent(this,ListView1Activity::class.java) startActivity(intent) } }
ficheiro: activity_main.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="#f0f0f0" android:padding="16dp" tools:context=".MainActivity"> <Button android:onClick="onListView1" android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:text="ListView XML array adapter" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
ficheiro: activity_list_view.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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=".ListView1Activity"> <ListView android:id="@+id/primeiraListView" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
ficheiro: arrays.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="dados_str"> <item>Portugal</item> <item>Espanha</item> <item>Franca</item> <item>Italia</item> <item>Alemanha</item> <item>Belgica</item> <item>Holanda</item> <item>Austria</item> <item>Luxemburgo</item> <item>Suecia</item> <item>Dinamarca</item> <item>Irlanda</item> <item>Croacia</item> <item>Eslovenia</item> <item>Eslovaquia</item> <item>Estonia</item> <item>Polonia</item> <item>Grecia</item> <item>Finlandia</item> <item>Chipre</item> <item>Malta</item> <item>Bulgaria</item> <item>Hungria</item> <item>Romenia</item> <item>Rep. Checa</item> <item>Letonia</item> <item>Lituania</item> </string-array> </resources>
ficheiro: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.deis.estuda.estudolistview"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Estudolistview"> <activity android:name=".ListView1Activity" android:label="ListView" android:parentActivityName=".MainActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ficheiro: ListView1Activity.kt
package pt.deis.estuda.estudolistview import android.os.Bundle import android.util.Log import android.widget.ArrayAdapter import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_list_view.* class ListView1Activity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_list_view) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.subtitle = "Exemplo XML array list" //uma lista não ordenada em arrays.xml val paises = resources.getStringArray(R.array.dados_str) paises.sort() //usar um adapter para mostrar a listview //contexto (actividades), layout que só tem uma textview, a fonte dos dados (array das strings) val adapter = ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,paises) primeiraListView.adapter = adapter primeiraListView.setOnItemClickListener() { parent, view, pos, id -> Log.i(TAG, "Item: $pos $id") } } }
ficheiro: build.gralde (Module)
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // obrigatorio para aceder aos diferentes layouts sem usar o findId } ...
em kotlin: uma calculadora
ficheiro: MainActivity.kt
package pt.deis.estuda.calculadora import android.graphics.Color import android.icu.number.NumberFormatter import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.Button import android.widget.TextView class MainActivity : AppCompatActivity() { lateinit var tvDisplay: TextView //variave para ligar a maquina var strDisplay = "0.0" var novoNumero = true //para tratar do % val numeroCorente : Double //caso dê erro converter fica com 0.0 //o então escrever error get()=strDisplay.toDoubleOrNull() ?: 0.0 //variavel para lidar com a operação //v1 /* enum class Ops{ NONE, ADD, SUB, MUL, DIv } var op = Ops.NONE */ //v2 //id da operação var operador = 0 //alterar a cor do operador set(value){ if(field !=0 ){ findViewById<Button>(field).setTextColor(Color.BLACK) } if(value !=0){ findViewById<Button>(value).setTextColor(Color.GREEN) } field =value } var numeroAntigo = 0.0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tvDisplay = findViewById(R.id.tvDisplay) updateDisplay() //para mostrar o 0.0 } fun updateDisplay(){ tvDisplay.text = strDisplay } fun onDigit(view: View) { ///ir buscar o texto do botão e adicionar à caixa val btn = view as Button //para resolver a situaçãod e ser a primeira vez if(novoNumero) { strDisplay = btn.text.toString() } else { strDisplay += btn.text //concatenar ao que lá está } updateDisplay() //para que efectivamente faça a concatenação novoNumero = false } fun onPonto(view: View) { //só pode exisir um ponto no numero if(novoNumero) { strDisplay = "0." }else{ //adicionar o ponto, mas testar se já existe if(strDisplay.contains('.')) return strDisplay += "." } updateDisplay() novoNumero = false } fun onAC(view: View) { strDisplay = "0.0" novoNumero = true updateDisplay() } fun onPM(view: View) { //o sinal do mais menos if(strDisplay[0] == '-'){ strDisplay = strDisplay.substring(1) }else{ //ou strDisplay = "-"+strDisplay //v1 strDisplay = "-$strDisplay" //v2 } updateDisplay() } fun onPer(view: View) { //dividir o valor que existe por 100 strDisplay = "" + numeroCorente / 100.0 updateDisplay() //talvez não usar o true //true: não permite acrescentar mais caracteres novoNumero = true } //versão individual do onOper //v1 fun onMais(view: View) {} fun onSub(view: View) {} fun onDiv(view: View) {} fun onMultiplica(view: View) {} //v2 fun onOper(view : View){ //manter as operações if(operador != 0 && !novoNumero){ onIgual(view) } numeroAntigo = numeroCorente novoNumero = true operador = view.id } fun onIgual(view: View) { var calculo = 0.0 when(operador){ R.id.bntMais -> calculo = numeroCorente + numeroAntigo R.id.btnMul -> calculo = numeroCorente * numeroAntigo R.id.bntSub -> calculo = numeroAntigo - numeroCorente R.id.bntDiv -> calculo = if(numeroCorente != 0.0) numeroAntigo / numeroCorente else 0.0 //caso não tenha operador para fazer else -> return } //actualizar de seguida o display strDisplay = "$calculo" novoNumero = true operador = 0 //manter o numero numeroAntigo = calculo updateDisplay() } }
ficheiro: themes.xml
<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%20name%3D%22Theme.Calculadora%22%20parent%3D%22Theme.AppCompat.Light.DarkActionBar%22%3E%0A%20%20%20%20%20%20%20%20%3C!--%20alterar%20o%20tema%20aqui.%20--%3E%0A%0A%20%20%20%20%20%20%20%20%3C!--%20cor%20preta%20default%20--%3E%0A%20%20%20%20%20%20%20%20%3Citem%20name%3D%22android%3AtextColor%22%3E%23000000%3C%2Fitem%3E%0A%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> </resources>
ficheiro: activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" android:background="#c0c0c0" android:padding="16dp" > <TextView android:id="@+id/tvDisplay" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="0.0" android:gravity="right" android:textSize="24sp" android:padding="16dp" android:background="#ffffc0" android:layout_marginBottom="20dp" /> <!-- android:layout_height="0dp" //distribuir o espaço da mesma forma (é o peso) android:layout_weight="1" //por termos peso a altura tem que ter 0dp --> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> <!-- android:id="@+id/bntAC" //atribuir sempre um id android:layout_weight="1" //distribuir o espaço da mesma forma (é o peso) android:layout_width="0dp" //por termos peso a largura tem que ter 0dp --> <Button android:id="@+id/bntAC" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="AC" android:textSize="20sp" android:onClick="onAC" /> <Button android:id="@+id/bntPM" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="+/-" android:textSize="20sp" android:onClick="onPM" /> <Button android:id="@+id/bntPerc" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="%" android:textSize="20sp" android:onClick="onPer" /> <Button android:id="@+id/bntDiv" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="/" android:textSize="20sp" android:onClick="onOper" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> <!-- android:id="@+id/bntAC" //atribuir sempre um id android:layout_weight="1" //distribuir o espaço da mesma forma (é o peso) android:layout_width="0dp" //por termos peso a largura tem que ter 0dp android:onClick="onDigit" é uma funça --> <Button android:id="@+id/bnt7" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="7" android:textSize="20sp" /> <Button android:id="@+id/bnt8" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="8" android:textSize="20sp" /> <Button android:id="@+id/bnt9" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="9" android:textSize="20sp" /> <Button android:id="@+id/btnMul" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="*" android:textSize="20sp" android:onClick="onOper" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> <!-- android:id="@+id/bntAC" //atribuir sempre um id android:layout_weight="1" //distribuir o espaço da mesma forma (é o peso) android:layout_width="0dp" //por termos peso a largura tem que ter 0dp --> <Button android:id="@+id/bnt4" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="4" android:textSize="20sp" /> <Button android:id="@+id/bnt5" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="5" android:textSize="20sp" /> <Button android:id="@+id/bnt6" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="6" android:textSize="20sp" /> <Button android:id="@+id/bntSub" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="-" android:textSize="20sp" android:onClick="onOper" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> <!-- android:id="@+id/bntAC" //atribuir sempre um id android:layout_weight="1" //distribuir o espaço da mesma forma (é o peso) android:layout_width="0dp" //por termos peso a largura tem que ter 0dp --> <Button android:id="@+id/bnt1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="1" android:textSize="20sp" /> <Button android:id="@+id/bnt2" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="2" android:textSize="20sp" /> <Button android:id="@+id/bnt3" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="onDigit" android:text="3" android:textSize="20sp" /> <Button android:id="@+id/bntMais" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="+" android:textSize="20sp" android:onClick="onOper" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> <!-- android:id="@+id/bntAC" //atribuir sempre um id android:layout_weight="1" //distribuir o espaço da mesma forma (é o peso) android:layout_width="0dp" //por termos peso a largura tem que ter 0dp --> <Button android:id="@+id/bnt0" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:onClick="onDigit" android:text="0" android:textSize="20sp" /> <Button android:id="@+id/bntPonto" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="." android:textSize="20sp" android:onClick="onPonto" /> <Button android:id="@+id/bntIgual" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="=" android:textSize="20sp" android:onClick="onIgual" /> </LinearLayout> </LinearLayout>