2015-12-02 39 views
1

我對Android非常陌生,而且我有一個問題,我不知道從哪裏開始尋找其原因。Android ListView充了兩次

我有一個片段ListView填充裝載器。 當我啓動應用程序的ListView顯示兩次,一個在另一個之上,這裏是它的外觀像一個截圖:

Duplicated list view

我不知道從哪裏開始尋找爲什麼出現這種情況,但我想我將不得不因此這裏給出一些代碼是我的片段代碼:

public class ForecastFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { 

    private static final int FORECAST_LOADER = 0; 
    // For the forecast view we're showing only a small subset of the stored data. 
    // Specify the columns we need. 
    private static final String[] FORECAST_COLUMNS = { 
      // In this case the id needs to be fully qualified with a table name, since 
      // the content provider joins the location & weather tables in the background 
      // (both have an _id column) 
      // On the one hand, that's annoying. On the other, you can search the weather table 
      // using the location set by the user, which is only in the Location table. 
      // So the convenience is worth it. 
      WeatherContract.WeatherEntry.TABLE_NAME + "." + WeatherContract.WeatherEntry._ID, 
      WeatherContract.WeatherEntry.COLUMN_DATE, 
      WeatherContract.WeatherEntry.COLUMN_SHORT_DESC, 
      WeatherContract.WeatherEntry.COLUMN_MAX_TEMP, 
      WeatherContract.WeatherEntry.COLUMN_MIN_TEMP, 
      WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING, 
      WeatherContract.WeatherEntry.COLUMN_WEATHER_ID, 
      WeatherContract.LocationEntry.COLUMN_COORD_LAT, 
      WeatherContract.LocationEntry.COLUMN_COORD_LONG 
    }; 

    // These indices are tied to FORECAST_COLUMNS. If FORECAST_COLUMNS changes, these 
    // must change. 
    static final int COL_WEATHER_ID = 0; 
    static final int COL_WEATHER_DATE = 1; 
    static final int COL_WEATHER_DESC = 2; 
    static final int COL_WEATHER_MAX_TEMP = 3; 
    static final int COL_WEATHER_MIN_TEMP = 4; 
    static final int COL_LOCATION_SETTING = 5; 
    static final int COL_WEATHER_CONDITION_ID = 6; 
    static final int COL_COORD_LAT = 7; 
    static final int COL_COORD_LONG = 8; 

    private ForecastAdapter mForecastAdapter; 

    public ForecastFragment() { 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     inflater.inflate(R.menu.menu_main, menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      startActivity(new Intent(getActivity(), SettingsActivity.class)); 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // The CursorAdapter will take data from our cursor and populate the ListView. 
     mForecastAdapter = new ForecastAdapter(getActivity(), null, 0); 

     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

     ListView listView = (ListView)rootView.findViewById(R.id.listview_forecast); 
     listView.setAdapter(mForecastAdapter); 

     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { 
       // CursorAdapter returns a cursor at the correct position for getItem(), or null 
       // if it cannot seek to that position 
       Cursor cursor = (Cursor) adapterView.getItemAtPosition(position); 
       if (cursor != null) { 
        String locationSetting = Utility.getPreferredLocation(getActivity()); 
        Intent detailIntent = new Intent(getActivity(), DetailActivity.class) 
          .setData(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
            locationSetting, cursor.getLong(COL_WEATHER_DATE) 
          )); 
        startActivity(detailIntent); 
       } 
      } 
     }); 
     return rootView; 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     getLoaderManager().initLoader(FORECAST_LOADER, null, this); 
     super.onActivityCreated(savedInstanceState); 
    } 

    private void updateWeather(){ 
     FetchWeatherTask weatherTask = new FetchWeatherTask(getActivity()); 
     String location = Utility.getPreferredLocation(getActivity()); 
     weatherTask.execute(location); 
    } 

    void onLocationChanged() { 
     updateWeather(); 
     getLoaderManager().restartLoader(FORECAST_LOADER, null, this); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     String location = Utility.getPreferredLocation(getActivity()); 

     //Sort order: Ascending by date 
     String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE + " ASC"; 
     Uri weatherForLocation = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate(
       location, System.currentTimeMillis()); 

     return new CursorLoader(getActivity(), 
       weatherForLocation, 
       FORECAST_COLUMNS, 
       null, 
       null, 
       sortOrder); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     if (!data.moveToFirst()) 
      updateWeather(); 
     mForecastAdapter.swapCursor(data); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     mForecastAdapter.swapCursor(null); 
    } 
} 
+1

您是否在活動的佈局中聲明瞭碎片,並在同一時間將其添加到事務中? – Blackbelt

+0

對不起我的無知,但你能告訴我你是什麼意思?我在這段代碼的'onCreateView'方法中查看rootView = inflater.inflate(R.layout.fragment_main,container,false);'content_main.xml'文件中:''那是什麼意思? –

+0

你可以發佈你的Activity的onCreate和它的佈局嗎? – Blackbelt

回答

2

從我所看到的截圖,它看起來像你添加了相同的片段兩次,當前視圖的層次結構。最常見的錯誤是在Activity的佈局中聲明片段,使用<fragment標記並以編程方式使用特定事務,這當然會導致屏幕上出現兩次相同的片斷。要修復它,請將佈局中的<fragment替換爲<FrameLayout,然後以編程方式添加片段。例如。

<FrameLayout 
    android:id="@+id/container" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 

,並在活動的onCreate

if (savedInstanceState == null){ 
    getSupportFragmentManager() .beginTransaction() .add(R.id.container, new ForecastFragment(), FORECASTFRAGMENT_TAG) .commit(); 
} 
+0

請問一個問題,我從xml佈局文件中刪除了這個'tools:layout =「@ layout/fragment_main」',但它沒有幫助,只是當我刪除這個'getSupportFragmentManager().beginTransaction().add(R。 id.container,新的F​​orecastFragment(),FORECASTFRAGMENT_TAG).commit();'它有幫助,我想不得不像這樣使用'getSupportFragmentManager().beginTransaction().add(R.id。容器,新的ForecastFragment(),FORECASTFRAGMENT_TAG).commit();'不在xml中。那麼,我該如何做到這一點? –

+0

您必須從xml中刪除整個' Blackbelt

+0

這是「content_main.xml」文件的內容:'如果我將它全部刪除它會給出一個錯誤,因爲該文件是空的... –

0

正在發生的事情是,你是通過XML聲明的片段,然後再充氣它

您應該使用更好的方法,而不是將片段放入XML中,添加一個空的framelayout並每次添加/替換片段(看看我在自定義庫中的this方法),這樣它只會顯示一次, 或不再膨脹它(但onResume也可以複製它,並且不提供更改顯示片段的自由)。

+0

非常感謝您的回答,這也是正確的 –