Почему TextView из другого файла макета не будет корректно запускать setText, но текстовые просмотры из activity_main будут?

#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);