30/09/2018, 22:05

Giúp về fragment bị đè (Tạo 2 lần)

Xin chào, mình đang học android bằng course trên Udacity, nhưng sau khi dùng đoạn code trong commit này:

GitHub

udacity/Sunshine-Version-2

Sunshine-Version-2 - The official repository for Developing Android Apps


Thì bị trùng lại Fragment, làm cho xuất hiện 2 fragment trùng lên nhau nhưng mình không thể fix được dù đã search Ai có time cũng như kinh nghiệm giúp mình xem thử với.
Đây là link project trên github:
https://github.com/lednhatkhanh/Sunshine
NOTE: Branch Sunshine_V2, 2 commit cuối cùng là nguyên nhân gây lỗi.
Mọi người xem giùm và mình xin cảm ơn rất nhiều.

Code đây:
MainActivity

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLocation = Utility.getPreferredLocation(this);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        if(savedInstanceState == null){
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment, new ForecastFragment(), FORECASTFRAGMENT_TAG)
                    .commit();
        }

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        String location = Utility.getPreferredLocation( this );
        // update the location in our second pane using the fragment manager
        if (location != null && !location.equals(mLocation)) {
            ForecastFragment ff = (ForecastFragment)getSupportFragmentManager().findFragmentByTag(FORECASTFRAGMENT_TAG);
            if ( null != ff ) {
                ff.onLocationChanged();
            }
            mLocation = location;
        }
    }`
ForecastFragment:
`@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);

        // Get a reference to the ListView, and attach this adapter to it.
        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 i, 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(i);
                if (cursor!=null){
                    String locationSetting = Utility.getPreferredLocation(getActivity());
                    Intent intent = new Intent(getActivity(), DetailActivity.class)
                            .setData(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
                                    locationSetting,
                                    cursor.getLong(COL_WEATHER_DATE)
                            ));
                    startActivity(intent);
                }
            }
        });

        return rootView;
    }

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

Thêm cái ảnh tình trạng hiện thời @@!

P/S: Đã fix được: https://stackoverflow.com/questions/37870882/oncreate-is-duplicating-views

Quân viết 00:20 ngày 01/10/2018

Có lỗi thì post code, post prj thì đến mùa quýt cũng không ai xem cho đâu

Le Dinh Nhat Khanh viết 00:10 ngày 01/10/2018

Project nó có cái commit đó, mà code đây ạ:
MainActivity:

> @Override
>     protected void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>         mLocation = Utility.getPreferredLocation(this);
>         setContentView(R.layout.activity_main);
>         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
>         setSupportActionBar(toolbar);

>         if(savedInstanceState == null){
>             getSupportFragmentManager().beginTransaction()
>                     .replace(R.id.fragment, new ForecastFragment(), FORECASTFRAGMENT_TAG)
>                     .commit();
>         }

>         FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
>         fab.setOnClickListener(new View.OnClickListener() {
>             @Override
>             public void onClick(View view) {
>                 Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
>                         .setAction("Action", null).show();
>             }
>         });
>     }

>     @Override
>     protected void onResume() {
>         super.onResume();
>         String location = Utility.getPreferredLocation( this );
>         // update the location in our second pane using the fragment manager
>         if (location != null && !location.equals(mLocation)) {
>             ForecastFragment ff = (ForecastFragment)getSupportFragmentManager().findFragmentByTag(FORECASTFRAGMENT_TAG);
>             if ( null != ff ) {
>                 ff.onLocationChanged();
>             }
>             mLocation = location;
>         }
>     }
ForecastFragment:
    @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);

            // Get a reference to the ListView, and attach this adapter to it.
            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 i, 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(i);
                    if (cursor!=null){
                        String locationSetting = Utility.getPreferredLocation(getActivity());
                        Intent intent = new Intent(getActivity(), DetailActivity.class)
                                .setData(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
                                        locationSetting,
                                        cursor.getLong(COL_WEATHER_DATE)
                                ));
                        startActivity(intent);
                    }
                }
            });

            return rootView;
        }

        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            getLoaderManager().initLoader(FORECAST_LOADER, null, this);
            super.onActivityCreated(savedInstanceState);
        }
Quân viết 00:06 ngày 01/10/2018

Nhìn không giống bị đè lắm, dễ là lỗi sinh ra trong adapter

Le Dinh Nhat Khanh viết 00:09 ngày 01/10/2018

Thế làm sao biết được đây ạ, chỉ khi tới commit này nó mới bị, từ đầu project mình không hề dùng đoạn
if(savedInstanceState == null)
trong MainActivity project thì hoàn toàn không có lỗi.

Quân viết 00:08 ngày 01/10/2018

Xml layout main đã tự create fragment rồi, Không cần tư tạo thêm đâu,bỏ cái đoạn if null ấy đi, chỗ get fragment by tag thay bằng get fragment by id

Le Dinh Nhat Khanh viết 00:10 ngày 01/10/2018

Đã fix được lỗi.
Vấn đề chính xác như bạn nói là layout đã tạo một fragment sẵn rồi, nhưng việc dùng đoạn code đó lại tạo thêm một fragment nữa, cách fix là bỏ fragment trong layout main và thay thế bằng FrameLayout với các thuộc tính tương tự.
Cảm ơn nhiều!

Bài liên quan
0