#java #android #xml #android-studio #android-viewpager
#java #Android #xml #android-studio #android-viewpager
Вопрос:
Предполагается, что программа запустит getCurrentLocation, а затем установит для TextView «coordinates» значение вызываемых координат. Это текстовое представление является частью представления пейджера, которое извлекается из отдельного XML-файла, отличного от основного макета «activity_main».
public class MainActivity extends AppCompatActivity
{
CardAdapter CardAdapter;
String coordinatesFinal;
FusedLocationProviderClient fusedLocationProviderClient;
TextView coordinates;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED amp;amp;
ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
getCurrentLocation();
}else
{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},100);
}
setupCardItems();
ViewPager2 CardViewPager = findViewById(R.id.cardViewPager);
CardViewPager.setAdapter(CardAdapter);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if (requestCode == 100 amp; grantResults.length > 0 amp;amp; (grantResults[0] grantResults[1]) == PackageManager.PERMISSION_GRANTED)
{
getCurrentLocation();
}else
{
Toast.makeText(getApplicationContext(), "Permission denied.",Toast.LENGTH_SHORT).show();
}
}
@SuppressLint("MissingPermission")
public void getCurrentLocation()
{
coordinates = findViewById(R.id.coordinates);
LocationManager locationManager = (LocationManager) getSystemService
(
Context.LOCATION_SERVICE
);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
fusedLocationProviderClient.getLastLocation().addOnCompleteListener(task ->
{
Location location = task.getResult();
if (location != null)
{
coordinates.setText(location.getLatitude() ", " location.getLongitude());
}else
{
LocationRequest locationRequest = new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(10000).setFastestInterval(1000).setNumUpdates(1);
LocationCallback locationCallback = new LocationCallback()
{
@Override
public void onLocationResult(LocationResult locationResult)
{
Location location1 = locationResult.getLastLocation();
coordinatesFinal = location1.getLatitude() ", " location1.getLongitude();
}
};
fusedLocationProviderClient.requestLocationUpdates(locationRequest,locationCallback, Looper.myLooper());
}
});
}else
{
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
//card view
private void setupCardItems()
{
List<CardItem> CardItems = new ArrayList<>();
CardItem itemPageOne = new CardItem();
itemPageOne.setLocation("Home");
itemPageOne.setTemp("60°f");
itemPageOne.setWeatherDesc("Cloudy");
itemPageOne.setWeatherIcon(R.drawable.cloud);
itemPageOne.setHum("75%");
itemPageOne.setVis("10");
itemPageOne.setPrecip("50%");
itemPageOne.setDew("40°f");
itemPageOne.setCloud("80%");
itemPageOne.setFog("75%");
CardItem itemPageTwo = new CardItem();
itemPageTwo.setLocation("Madison");
itemPageTwo.setTemp("60°f");
itemPageTwo.setWeatherDesc("Sunny");
itemPageTwo.setWeatherIcon(R.drawable.sun);
itemPageTwo.setHum("75%");
itemPageTwo.setVis("10");
itemPageTwo.setPrecip("50%");
itemPageTwo.setDew("40°f");
itemPageTwo.setCloud("80%");
itemPageTwo.setFog("75%");
CardItem itemPageThree = new CardItem();
itemPageThree.setLocation("Milwaukee");
itemPageThree.setTemp("60°f");
itemPageThree.setWeatherDesc("Rainy");
itemPageThree.setWeatherIcon(R.drawable.rain);
itemPageThree.setHum("75%");
itemPageThree.setVis("10");
itemPageThree.setPrecip("50%");
itemPageThree.setDew("40°f");
itemPageThree.setCloud("80%");
itemPageThree.setFog("75%");
CardItems.add(itemPageOne);
CardItems.add(itemPageTwo);
CardItems.add(itemPageThree);
CardAdapter = new CardAdapter(CardItems);
}
}
Я сузил его до строки, которая не работает должным образом:
coordinates.setText(location.getLatitude() ", " location.getLongitude());
Я протестировал точно такую же строку, как указано выше, только используя TextView изнутри activity main, который работает просто отлично. Любая помощь приветствуется.
Редактировать: файл на самом деле аварийно завершает работу, я по ошибке сказал, что это не так, и я добавил оба файла .xml:
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="#566D8F"
tools:context=".MainActivity">
<LinearLayout
android:id="@ id/topBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<ImageButton
android:id="@ id/settingsBar2"
android:layout_width="27sp"
android:layout_height="27sp"
android:layout_gravity="left"
android:layout_marginStart="20sp"
android:layout_marginEnd="70sp"
android:background="@color/background"
android:cropToPadding="true"
android:scaleType="fitCenter" />
<TextView
android:id="@ id/homeName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fontFamily="sans-serif-condensed-light"
android:gravity="center_horizontal"
android:maxLines="1"
android:text="@string/app_name"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:typeface="normal" />
<ImageButton
android:id="@ id/settingsBar"
android:layout_width="27sp"
android:layout_height="27sp"
android:layout_gravity="right"
android:layout_marginStart="70sp"
android:layout_marginEnd="20sp"
android:background="@drawable/settings_handle"
android:cropToPadding="true"
android:scaleType="fitCenter" />
</LinearLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@ id/cardViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@ id/topBar" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_container_card.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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="20dp">
<androidx.cardview.widget.CardView
android:id="@ id/pagerCard"
android:layout_width="match_parent"
android:layout_height="440dp"
android:layout_margin="20dp"
app:cardBackgroundColor="#EAC0A0"
app:cardCornerRadius="30dp"
app:cardElevation="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@ id/locationName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed-medium"
android:gravity="center"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@ id/coordinates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed-light"
android:gravity="center"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView
android:id="@ id/temperature"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-black"
android:gravity="center"
android:textColor="@color/white"
android:textSize="50sp" />
<TextView
android:id="@ id/weatherDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed-light"
android:gravity="center"
android:textColor="@color/white"
android:textSize="12sp" />
<ImageView
android:id="@ id/imageOnboarding"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_margin="15dp"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<TextView
android:id="@ id/humidity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-light"
android:paddingLeft="30sp"
android:paddingBottom="5sp"
android:text="Humidity"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/humVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-medium"
android:paddingStart="10sp"
android:paddingEnd="15sp"
android:paddingBottom="5sp"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/visibility"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed-light"
android:paddingStart="15sp"
android:paddingEnd="10sp"
android:paddingBottom="5sp"
android:text="Visibility"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/visVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-medium"
android:paddingStart="10sp"
android:paddingRight="30sp"
android:paddingBottom="5sp"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<TextView
android:id="@ id/precipitation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-light"
android:paddingLeft="30sp"
android:paddingTop="5sp"
android:paddingBottom="5sp"
android:text="Precip. "
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/precipVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-medium"
android:paddingStart="10sp"
android:paddingTop="5sp"
android:paddingEnd="15sp"
android:paddingBottom="5sp"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/dewPoint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed-light"
android:paddingStart="15sp"
android:paddingTop="5sp"
android:paddingBottom="5sp"
android:text="Dew Point"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/dewVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-medium"
android:paddingStart="10sp"
android:paddingTop="5sp"
android:paddingRight="30sp"
android:paddingBottom="5sp"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<TextView
android:id="@ id/cloud"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-light"
android:paddingLeft="30sp"
android:paddingTop="5sp"
android:paddingBottom="5sp"
android:text="Cloud"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/cloudVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-medium"
android:paddingStart="10sp"
android:paddingTop="5sp"
android:paddingEnd="15sp"
android:paddingBottom="5sp"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/fog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed-light"
android:paddingStart="15sp"
android:paddingTop="5sp"
android:paddingBottom="5sp"
android:text="Fog"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<TextView
android:id="@ id/fogVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
android:fontFamily="sans-serif-condensed-medium"
android:paddingStart="10sp"
android:paddingTop="5sp"
android:paddingEnd="30sp"
android:paddingBottom="5sp"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</TableRow>
</TableLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
Edit 2: CardAdapter.java and CardItem.java
CardAdapter.java:
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.cardViewHolder>
{
private List<CardItem> CardItems;
public CardAdapter(List<CardItem> CardItems) {
this.CardItems = CardItems;
}
@NonNull
@Override
public cardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new cardViewHolder(
LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_container_card, parent, false
)
);
}
@Override
public void onBindViewHolder(@NonNull cardViewHolder holder, int position) {
holder.setCardData(CardItems.get(position));
}
@Override
public int getItemCount() {
return CardItems.size();
}
class cardViewHolder extends RecyclerView.ViewHolder
{
private TextView locationText;
private TextView weatherDesc;
private ImageView weatherIcon;
private TextView tempVal;
private TextView humVal;
private TextView visVal;
private TextView precipVal;
private TextView dewVal;
private TextView cloudVal;
private TextView fogVal;
public cardViewHolder(@NonNull View itemView)
{
super(itemView);
locationText = itemView.findViewById(R.id.locationName);
weatherDesc = itemView.findViewById(R.id.weatherDesc);
weatherIcon = itemView.findViewById(R.id.imageOnboarding);
tempVal = itemView.findViewById(R.id.temperature);
humVal = itemView.findViewById(R.id.humVal);
visVal = itemView.findViewById(R.id.visVal);
precipVal = itemView.findViewById(R.id.precipVal);
dewVal = itemView.findViewById(R.id.dewVal);
cloudVal = itemView.findViewById(R.id.cloudVal);
fogVal = itemView.findViewById(R.id.fogVal);
}
void setCardData(CardItem CardItem)
{
locationText.setText(CardItem.getLocation());
weatherDesc.setText(CardItem.getWeatherDesc());
weatherIcon.setImageResource(CardItem.getWeatherIcon());
tempVal.setText(CardItem.getTemp());
humVal.setText(CardItem.getHum());
visVal.setText(CardItem.getVis());
precipVal.setText(CardItem.getPrecip());
dewVal.setText(CardItem.getDew());
cloudVal.setText(CardItem.getCloud());
fogVal.setText(CardItem.getFog());
}
}
}
CardItem.java:
package com.example.viewpagertest;
public class CardItem
{
private int weatherIcon;
private String location;
private String temp;
private String weatherDesc;
private String hum;
private String vis;
private String precip;
private String dew;
private String cloud;
private String fog;
//weather icon
public int getWeatherIcon() {
return weatherIcon;
}
public void setWeatherIcon(int weatherIcon) {
this.weatherIcon = weatherIcon;
}
//location title
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
//temperature value
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
//weather description
public String getWeatherDesc() {
return weatherDesc;
}
public void setWeatherDesc(String weatherDesc) {
this.weatherDesc = weatherDesc;
}
//humidity value
public String getHum() {
return hum;
}
public void setHum(String hum) {
this.hum = hum;
}
//visibility value
public String getVis() {
return vis;
}
public void setVis(String vis) {
this.vis = vis;
}
//precipitation value
public String getPrecip() {
return precip;
}
public void setPrecip(String precip) {
this.precip = precip;
}
//dew point value
public String getDew() {
return dew;
}
public void setDew(String dew) {
this.dew = dew;
}
//cloud value
public String getCloud() {
return cloud;
}
public void setCloud(String cloud) {
this.cloud = cloud;
}
//fog value
public String getFog() {
return fog;
}
public void setFog(String fog) {
this.fog = fog;
}
}
Вот консоль при запуске отладчика с точкой останова в
coordinates.setText(location.getLatitude() ", " location.getLongitude());
Вся консоль нарушает ограничение на количество символов, поэтому вот документ с текстом консоли.
Комментарии:
1. показать журнал ошибок.
2. Извините, это не сбой, просто не устанавливает TextView ни на что. Этого не происходит при использовании TextView из activity_main вместо XML-файла viewpager .
3. Повторите и установите точку останова
coordinates.setText(location.getLatitude() ", " location.getLongitude());
в этой строке, затем опубликуйте полученную информацию4. Если TextView отсутствует в основном макете, который вы не можете просто использовать
findViewById
, вам придется использоватьcardViewPager.findViewById
. Но пожалуйста, включите оба XML-файла, чтобы мы могли помочь5. Да, это должно привести к сбою, какую информацию вы получаете в отладчике Android?
Ответ №1:
if (location != null)
{
// coordinates.setText(location.getLatitude() ", " location.getLongitude());
cardAdapter.setCoordinates(0 /*the cardItem number you want to update*/, location.getLatitude() ", " location.getLongitude());
}
Поскольку текстовое представление координат находится в вашем элементе xml, вы не сможете обращаться к нему из корня вашего MainActivity, но из вашего элемента.
Обновить
Спасибо за добавление кода адаптера:
Проще всего было бы создать метод в вашем адаптере следующим образом:
setCoordinates(int position, String coords) {
holders.get(position).itemView.findViewById(R.id.coordinates).setText(coords);
}
Чтобы иметь доступ к держателям во время выполнения, добавьте следующее:
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.cardViewHolder>
{
private List<CardItem> cardItems;
private List<CardViewHolder> holders;
....
@Override
public cardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
CardViewHolder holder = new cardViewHolder(
LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_container_card, parent, false
)
);
holders.add(holder);
return holder;
}
Другим вариантом было бы добавить поле coordinates
в свой CardItem
и написать setCoordinates
метод следующим образом:
setCoordinates(int position, String coords) {
cardItems.get(position).setCoordinates(coords);
notifyDataSetChanged(); // to reload the holders, only notifying the specific position will be faster to reload only the changed holder
}
Комментарии:
1. Как бы я тогда вызвал координаты GPS из метода getCurrentLocation в MainActivity?
2. @FletcherCrone в вашем MainActivity вам нужно только изменить одну строку
setText
на строку в верхней части моего ответа
Ответ №2:
Вам нужно обновить элементы адаптера, создав метод в CardAdapter и вызвав его из main activity, как показано ниже —
Создайте этот метод в своем классе адаптера
public void updateAdapter(List<CardItem> CardItems) {
this.CardItems = CardItems;
notifyDataSetChanged();
}
Замените строку ниже
CardAdapter = new CardAdapter(CardItems);
С этим
CardAdapter.updateAdapter(CardItems);