2017-11-08 8 views
0

OpenWeatherMap API를 사용하여 일기 예보 앱을 개발 중이며 사용자가 다른 도시의 데이터를 가져 오려고 할 때 앱을 새로 고치지 않는 한 모든 것이 부드럽고 멋지게 진행됩니다. 서버 호출 및 실제 데이터를 반환합니다. 즉, 새로 고쳐야하지만 조각은 조각으로 업데이트되지 않습니다.새로 고침 호출 후 Refresh되지 않는 ViewPager

이 MainActivity 클래스 세그먼트 :

public class MainActivity extends AppCompatActivity 
      implements 
      NavigationView.OnNavigationItemSelectedListener { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     session = new SessionManagement(MainActivity.this); 
     initComponents(); 
    } 

    private void initComponents() { 
     //Initializes the components that the MainActivity layout has 
     city = getResources().getString(R.string.default_city); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
     ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
       this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
     drawer.setDrawerListener(toggle); 
     toggle.syncState(); 
     navigationView = (NavigationView) findViewById(R.id.nav_view); 
     navigationView.setNavigationItemSelectedListener(this); 
     View navigationViewHeader = navigationView.getHeaderView(0); 
     mHeaderCityName = (TextView) navigationViewHeader.findViewById(R.id.tv_current_city); 
     mHeaderCityTemp = (TextView) navigationViewHeader.findViewById(R.id.tv_current_city_temp); 
     mFavCities = (ListView) navigationView.findViewById(R.id.lv_favorite_cities); 
     mTabs = (TabLayout) findViewById(R.id.tl_tabs); 
     mPages = (ViewPager) findViewById(R.id.vp_view_pager); 
     progressDialog = new ProgressDialog(MainActivity.this); 
     adapter = new MeteoPlusPagerAdapter(getSupportFragmentManager()); 
     mTabs.setupWithViewPager(mPages); 
     savedCities = new ArrayList<>(); 
     favoriteCities = new ArrayList<>(); 
     citiesAdapter = new ArrayAdapter<>(this, 
       android.R.layout.simple_list_item_1, android.R.id.text1, favoriteCities); 
     mFavCities.setAdapter(citiesAdapter); 
     if (session.getFavorites() != null) { 
      savedCities = new ArrayList<>(session.getFavorites()); 

      if (savedCities.size() > 0) { 
       favoriteCities.addAll(savedCities); 
       citiesAdapter.notifyDataSetChanged(); 
       TextView mNoFavs = (TextView) navigationView.findViewById(R.id.tv_no_favorites); 
       mNoFavs.setVisibility(View.GONE); 
       mFavCities.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
        @Override 
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { 
         fetchWeatherData((String) adapterView.getAdapter().getItem(position)); 
        } 
       }); 
      } 
     } 
     if (citiesAdapter.getCount() == 0) { 
      TextView mNoFavs = (TextView) navigationView.findViewById(R.id.tv_no_favorites); 
      mNoFavs.setVisibility(View.VISIBLE); 
      mFavCities.setVisibility(View.GONE); 
      mFavCities.setEmptyView(navigationView.findViewById(R.id.tv_no_favorites)); 
     } 

    } 

    /** 
    * Fetches data for weather preferences from server 
    * 
    * @param city 
    */ 
    void fetchWeatherData(final String city) { 
     final ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); 
     String appId = getResources().getString(R.string.openweathermap_appid); 
     Call<WeatherResponse> call = apiService.getCurrentWeatherDataSingleLocation(city, appId); 
     progressDialog.setMessage("Fetching data. Please wait..."); 
     progressDialog.show(); 
     call.enqueue(new Callback<WeatherResponse>() { 
      @Override 
      public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) { 
       progressDialog.dismiss(); 
       weatherResponse = response.body(); 
       mHeaderCityName.setText(city); 
       Log.d("city",weatherResponse.getCityName());//after refresh correct data returned 
       Log.d("cityId",Integer.toString(weatherResponse.getId()));//after refresh correct data returned 
       String identifier = isFahrenheit ? "°F" : "°C"; 
       String temperature = String.format("%.0f " + identifier, 
         MeteoPlusUtility.convert(weatherResponse.getMain().getTemperature(), isFahrenheit)); 
       mHeaderCityTemp.setText(temperature); 
       if (adapter.getCount() > 0) { 
        adapter.clear(); 
        adapter.notifyDataSetChanged(); 
       } 
       setupViewPager(mPages, weatherResponse); 
       //adapter.notifyDataSetChanged(); 
       getSupportActionBar().setTitle(weatherResponse.getCityName()); 
      } 

      @Override 
      public void onFailure(Call<WeatherResponse> call, Throwable t) { 
       progressDialog.dismiss(); 
       call.cancel(); 
       Toast.makeText(MainActivity.this, "Failed to obtain results!!", Toast.LENGTH_SHORT).show(); 
       call.cancel(); 
       // Log.e("API_CALL", t.getMessage()); 
      } 
     }); 
    } 

    /** 
    * @param viewPager the actual viewpager of the activity 
    */ 
    private void setupViewPager(ViewPager viewPager, WeatherResponse weatherResponse) { 
     //Sets up the whole view pager with all the pages in it 
     if (weatherResponse != null) { 
      String city = weatherResponse.getCityName(); 
      String id = String.valueOf(weatherResponse.getId()); 
      adapter.addFragment(NowFragment.newInstance(city), "Now"); 
      adapter.addFragment(FiveDayThreeHourFragment.newInstance(id), "5 day/3 hour"); 
      adapter.addFragment(DailyFragment.newInstance(id, "16"), "Daily"); 
      viewPager.setAdapter(adapter); 
     } else { 
      Toast.makeText(MainActivity.this, "No data", Toast.LENGTH_SHORT).show(); 
     } 

    } 


    private void displayAnotherCity() { 
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this); 
     alertDialog.setTitle("Select city"); 
     alertDialog.setMessage("Please enter city"); 

     final EditText input = new EditText(MainActivity.this); 
     LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
       LinearLayout.LayoutParams.MATCH_PARENT, 
       LinearLayout.LayoutParams.MATCH_PARENT); 
     input.setLayoutParams(lp); 
     alertDialog.setView(input); 
     alertDialog.setIcon(R.mipmap.app_logo); 

     alertDialog.setPositiveButton("Confirm", 
       new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         fetchWeatherData(input.getText().toString()); 
         adapter.notifyDataSetChanged(); 
         dialog.dismiss(); 
        } 
       }); 

     alertDialog.setNegativeButton("Cancel", 
       new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         dialog.cancel(); 
        } 
       }); 

     alertDialog.show(); 
    } 

는 그리고 이것은 NowFragment 세그먼트 모든 프래그먼트 채우기이며 onActivityCreated 방법에서와 동일한 방식으로 데이터를 페치.

@Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View mNow = LayoutInflater.from(getContext()).inflate(R.layout.tab_now, container, false); 

     initComponents(mNow); 
     return mNow; 
    } 

    /** 
    * fetches data from server and populates the view 
    * 
    * @param city 
    */ 
    void fetchWeatherData(String city) { 
     ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); 
     String appId = getResources().getString(R.string.openweathermap_appid); 
     Call<WeatherResponse> call = apiService.getCurrentWeatherDataSingleLocation(city, appId); 

     call.enqueue(new Callback<WeatherResponse>() { 
      @Override 
      public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) { 
       progressDialog.dismiss(); 
       weatherData = response.body(); 
       prepareData(weatherData); 
      } 

      @Override 
      public void onFailure(Call<WeatherResponse> call, Throwable t) { 
       call.cancel(); 
       Toast.makeText(getContext(), "Failed to obtain results!!", Toast.LENGTH_SHORT).show(); 
       Log.e("API_CALL", t.getMessage()); 
      } 
     }); 
    } 

    /** 
    * Intitializes the elements of the view 
    * 
    * @param view the view to display 
    */ 
    private void initComponents(View view) { 
     city = getArguments().getString(MeteoPlusUtility.TAG_CURRENT_WEATHER); 
     mCurrenTime = (TextView) view.findViewById(R.id.tv_current_time); 
     mWeatherTemperature = (TextView) view.findViewById(R.id.tv_weather_temperature); 
     mWeatherMain = (TextView) view.findViewById(R.id.tv_weather_main); 
     mWeatherDescription = (TextView) view.findViewById(R.id.tv_weather_description); 
     mWeatherHumidity = (TextView) view.findViewById(R.id.tv_weather_humidity); 
     mWeatherWindSpeed = (TextView) view.findViewById(R.id.tv_weather_wind_speed); 
     mWeatherPressure = (TextView) view.findViewById(R.id.tv_weather_pressure); 
     mWeatherHighTemp = (TextView) view.findViewById(R.id.tv_weather_high_temp); 
     mWeatherLowTemp = (TextView) view.findViewById(R.id.tv_weather_low_temp); 
     mWeatherSunrise = (TextView) view.findViewById(R.id.tv_weather_sunrise); 
     mWeatherSunset = (TextView) view.findViewById(R.id.tv_weather_sunset); 
     mWeatherDataCalculation = (TextView) view.findViewById(R.id.tv_weather_dt); 
     mWeatherIcon = (ImageView) view.findViewById(R.id.iv_weather_icon); 
     progressDialog = new ProgressDialog(getContext()); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     refreshData(); 
    } 

    @Override 
    public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     refreshData(); 
    } 


    /** 
    * prepares all the data fetched from server to the corresponding elements in the layout 
    * 
    * @param wData response from server 
    */ 
    private void prepareData(WeatherResponse wData) { 
     if (wData != null) { 
      MainWeatherData mainWeatherData = wData.getMain(); 
      List<Weather> wList = wData.getWeatherList(); 
      Weather generalWeatherData = wList.get(0); 
      Wind wind = wData.getWind(); 
      WeatherSystem sys = wData.getSys(); 
      String identifier = isFahrenheit ? "°F" : "°C"; 
      Uri uri = Uri.parse(MeteoPlusUtility.OPENWEATHER_ICON_URL + generalWeatherData.getIconId() + ".png"); 
      Picasso.with(getContext()).load(uri).resize(300, 300).centerInside().into(mWeatherIcon); 
      mCurrenTime.setText(MeteoPlusUtility.currentDateToString()); 
      String temperature = String.format("%.0f " + identifier, MeteoPlusUtility.convert(mainWeatherData.getTemperature(), isFahrenheit)); 
      mWeatherTemperature.setText(temperature); 
      mWeatherMain.setText(generalWeatherData.getMain()); 
      mWeatherDescription.setText(generalWeatherData.getDescription()); 
      String humidity = String.valueOf(mainWeatherData.getHumidity()) + " %"; 
      mWeatherHumidity.setText(humidity); 
      String windSpeed = String.valueOf(wind.getSpeed()) + " KPH"; 
      mWeatherWindSpeed.setText(windSpeed); 
      String pressure = String.valueOf(mainWeatherData.getPressure()) + " hPa"; 
      mWeatherPressure.setText(pressure); 
      String lowTemp = String.format("%.0f " + identifier, MeteoPlusUtility.convert(mainWeatherData.getTempMin(), isFahrenheit)); 
      mWeatherLowTemp.setText(lowTemp); 
      String highTemp = String.format("%.0f " + identifier, MeteoPlusUtility.convert(mainWeatherData.getTempMax(), isFahrenheit)); 
      mWeatherHighTemp.setText(highTemp); 
      mWeatherSunrise.setText(MeteoPlusUtility.getTimeInPreetyFormat(sys.getSunrise(), 
        new SimpleDateFormat("HH:mm zzz"))); 
      mWeatherSunset.setText(MeteoPlusUtility.getTimeInPreetyFormat(sys.getSunset(), 
        new SimpleDateFormat("HH:mm zzz"))); 
      mWeatherDataCalculation.setText(MeteoPlusUtility.getTimeInPreetyFormat(wData.getTimeofDataCalculation(), new SimpleDateFormat("HH:mm zzz"))); 
     } 
    } 


    /** 
    * creates instance of the fragment 
    * 
    * @param city used for data fetch 
    * @return fragment 
    */ 
    public static NowFragment newInstance(String city) { 
     NowFragment nowFragment = new NowFragment(); 
     Bundle args = new Bundle(); 
     args.putString(MeteoPlusUtility.TAG_CURRENT_WEATHER, city); 
     nowFragment.setArguments(args); 

     return nowFragment; 
    } 

    @Override 
    public void setArguments(Bundle args) { 
     super.setArguments(args); 
    } 

    @Override 
    public void refreshData() { 
     fetchWeatherData(city); 
    } 

이것은 ViewPagerAdapter 코드 :

public class MeteoPlusPagerAdapter extends FragmentPagerAdapter { 
    private final List<Fragment> mFragments = new ArrayList<>(); 
    private final List<String> mFragmentsTitles = new ArrayList<>(); 

    public MeteoPlusPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragments.get(position); 
    } 

    @Override 
    public int getCount() { 
     return mFragments.size(); 
    } 

    /** 
    * adds fragment and title for the fragment to the corresponding lists 
    * 
    * @param fragment Fragment to be added 
    * @param title title of the added fragment 
    */ 
    public void addFragment(Fragment fragment, String title) { 
     //Adds fragment to the view pager with title to be displayed in the tab layout 
     mFragments.add(fragment); 
     mFragmentsTitles.add(title); 
    } 
    public void clear(){ 
     mFragments.clear(); 
     mFragmentsTitles.clear(); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
//  if (object instanceof NowFragment) { 
//   ((NowFragment) object).refreshData(); 
//  } else if (object instanceof FiveDayThreeHourFragment) { 
//   ((FiveDayThreeHourFragment) object).refreshData(); 
//  } else if (object instanceof DailyFragment) { 
//   ((DailyFragment) object).refreshData(); 
//  } 
//  return super.getItemPosition(object); 
     return POSITION_NONE; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mFragmentsTitles.get(position); 
    } 

나는이에 의해 정말 짜증이야, 나는 디버깅 및 세부 검사, 솔루션하지만 결과를 검색하여 문제의 원인을 찾을 수없는, 도와주세요.

+0

에 대한 notifyDataSetChanged를 호출해야? – nhoxbypass

+0

@nhoxbypass 뷰어의 조각을 복제하기 때문에 어댑터를 지우는 코드를 추가했는데 복제 된 조각에 올바른 데이터가 있기를 원하지 않지만 viewpager에 중복 된 조각이 없도록하고 기존 조각을 업데이트했습니다. 그래서 중복을 제거하기위한 해결 방법을 취해야했습니다. –

답변

0
 return POSITION_NONE; 

당신은 매번`fetchWeatherData은()`호출되는 어댑터

당신은 ViewPager` '의 기존의 모든 조각을 지우고 새로운 조각을 추가 할