简体   繁体   中英

ScrollView savedInstanceState always @NotNull parameter

Have been trying to understand this for day's now but just must be doing something wrong. I want to be able to restore the position in ScrollView on orientation change and when returning after video activity (info).

Here is my complete code without any of my 999 different failed code attempts

ScrollView android:id="@+id/ mScrollView "

package com.miniteve.activity;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import com.kaltura.client.enums.KalturaMediaType;
import com.kaltura.client.types.KalturaBaseEntry;
import com.kaltura.client.types.KalturaMediaEntry;
import com.kaltura.client.types.KalturaMediaEntryFilter;
import com.miniteve.components.GridForLand;
import com.miniteve.components.GridForPort;
import com.miniteve.components.ItemGrid;
import com.miniteve.enums.States;
import com.miniteve.mediatorActivity.TemplateActivity;
import com.miniteve.services.Media;
import com.miniteve.utils.Utils;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Observable;
import java.util.Observer;



public class VideoCategory extends TemplateActivity implements Observer {

    private final DownloadListCatigoriesTask downloadTask;
    private List<KalturaMediaEntry> listEntries;
    private List<KalturaMediaEntry> copyEntries;
    private int categoryId;
    private String categoryName;
    private KalturaMediaEntry lastCreatedEntry;
    private RelativeLayout rl_category;
    private Activity activity;
    private LinearLayout ll_base;
    private RelativeLayout menu;
    private List<GridForPort> contentPort;
    private List<GridForLand> contentLand;
    private int orientation;
    private boolean listCategoriesIsLoaded = false;
    private List<ProgressBar> progressBar;
    private int k = 0;


    public VideoCategory() {
        listEntries = new ArrayList<KalturaMediaEntry>();
        copyEntries = new ArrayList<KalturaMediaEntry>();
        downloadTask = new DownloadListCatigoriesTask();
        new HashMap<KalturaMediaEntry, Bitmap>();
        lastCreatedEntry = new KalturaMediaEntry();

    }





    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
        setContentView(R.layout.category);
        Configuration c = getResources().getConfiguration();
        orientation = c.orientation;

        setView();
        activity = this;
        extractBundle();
        ll_base = (LinearLayout) findViewById(R.id.ll_base);
        rl_category.setVisibility(View.INVISIBLE);
        menu.setVisibility(View.INVISIBLE);




        // check display size to figure out what image resolution will be loaded
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
        Point size1 = new Point();
        display.getRealSize(size1);

        switch (orientation) {
            case Configuration.ORIENTATION_PORTRAIT:
            case Configuration.ORIENTATION_UNDEFINED:
                downloadTask.execute();
                break;
            case Configuration.ORIENTATION_LANDSCAPE:
                downloadTask.execute();
                break;
            default:
                break;
        }
    }








    private void extractBundle() {
        try {
            Bundle extras = getIntent().getExtras();
            assert extras != null;
            categoryId = extras.getInt("categoryId");
            categoryName = extras.getString("categoryName");
        } catch (Exception e) {
            e.printStackTrace();
            categoryId = 0;
            categoryName = "";
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.category);
        this.orientation = newConfig.orientation;
        ll_base = (LinearLayout) findViewById(R.id.ll_base);

        setView();
        if (listCategoriesIsLoaded) {
            updateData(listEntries);
        }
    }

    private void setView() {
        rl_category = (RelativeLayout) findViewById(R.id.rl_category);
        ll_base = (LinearLayout) findViewById(R.id.ll_base);
        menu = (RelativeLayout) findViewById(R.id.menu);
    }


    //Called to process touch screen events.
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_MOVE:

                break;
        }
        return super.dispatchTouchEvent(ev);
    }


    public void cats(View view) {
        // Do something in response to button
        menu.setVisibility(View.VISIBLE);
    }

    public void vehicles(View view) {
        // Do something in response to button
        getActivityMediator().showVideoCategory(12);
    }

    public void funny(View view) {
        // Do something in response to button
        getActivityMediator().showVideoCategory(11);
    }

    public void music(View view) {
        // Do something in response to button
        getActivityMediator().showVideoCategory(10);
    }

    public void animals(View view) {
        // Do something in response to button1
        getActivityMediator().showVideoCategory(9);
    }


    public void close(View view) {
        // Do something in response to button

        menu.setVisibility(View.INVISIBLE);

    }


    public void back(View view) {
        // Do something in response to button

        getActivityMediator().showMostPopular();

    }


    public void onClick(View v) {
        switch (v.getId()) {

            case R.id.iv_thumbnail:
                getActivityMediator().showInfo(lastCreatedEntry.id, categoryName, lastCreatedEntry.partnerId);
                break;

        }



    }





    private void ImageLoader() {

        // check display size to figure out what image resolution will be loaded
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
        Point size1 = new Point();
        display.getRealSize(size1);


        Log.w(TAG, "Start image loader");
        float scale = (float) size1.x / (float) size1.y;
        DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisc(true).imageScaleType(ImageScaleType.IN_SAMPLE_INT).bitmapConfig(Bitmap.Config.RGB_565).build();

        // This configuration tuning is custom. You can tune every option, you may tune some of them,
        // or you can create default configuration by
        //  ImageLoaderConfiguration.createDefault(this);
        // method.
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(activity)
                .threadPoolSize(3).threadPriority(Thread.NORM_PRIORITY - 2).memoryCacheSize(256000000) // 256 Mb
                .discCacheSize(150000000) // 150 Mb
                .denyCacheImageMultipleSizesInMemory().defaultDisplayImageOptions(options)
                .enableLogging().build();
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);
        imageLoader.init(config);


        final List<String> url = new ArrayList<String>();
        List<ImageView> view = new ArrayList<ImageView>();
        progressBar = new ArrayList<ProgressBar>();

        for (KalturaMediaEntry entry : copyEntries) {
            url.add(entry.thumbnailUrl + "/width/738/height/404");
        }
        int count = 0;
        for (String string : url) {
            Log.w(TAG, "url: " + count++ + " " + string);
        }

        int state = 0;
        count = 0;
        for (KalturaMediaEntry copyEntry : copyEntries) {
            ItemGrid ig = null;
            switch (orientation) {

                case Configuration.ORIENTATION_PORTRAIT:
                    switch (state) {
                        case 0:
                            //left
                            Log.w(TAG, "xl: " + count);
                            ig = contentPort.get(count).getLeftItemGrid();
                            state = 2;
                            break;
                        case 2:
                            //right
                            Log.w(TAG, "xr: " + count);
                            ig = contentPort.get(count).getRightItemGrid();
                            count++;
                            state = 0;
                            break;
                    }
                    break;

                case Configuration.ORIENTATION_LANDSCAPE:
                    switch (state) {
                        case 0:
                            //left
                            Log.w(TAG, "xl: " + count);
                            ig = contentLand.get(count).getLeftItemGrid();
                            state = 1;
                            break;
                        case 1:
                            //center
                            Log.w(TAG, "xc: " + count);
                            ig = contentLand.get(count).getCenterItemGrid();
                            state = 2;
                            break;
                        case 2:
                            //right
                            Log.w(TAG, "xr: " + count);
                            ig = contentLand.get(count).getRightItemGrid();
                            count++;
                            state = 0;
                            break;
                    }
                    break;
                default:
                    break;
            }
            if (ig != null) {
                view.add(ig.getThumb());
                progressBar.add(ig.getProgressBar());
            }
        }

        count = 0;
        Log.w(TAG, "size: " + progressBar.size());
        k = 0;
        for (String string : url) {
            if (string != null) {
                imageLoader.displayImage(string, view.get(count), new ImageLoadingListener() {

                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                        // do nothing
                        Log.w(TAG, "onLoadingStarted");

                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view,
                                                FailReason failReason) {
                        Log.w(TAG, "onLoadingFailed");
                        imageLoader.clearMemoryCache();
                        imageLoader.clearDiscCache();

                    }

                    @Override
                    public void onLoadingComplete(String imageUri, View view,
                                                  Bitmap loadedImage) {
                        // do nothing

                        if (k < progressBar.size()) {

                            progressBar.get(k++).setVisibility(View.GONE);

                        }

                        Log.w(TAG, "onLoadingComplete: " + k);

                        Log.w(TAG, "k<>size: " + k + "--" + url.size());
                        if (k >= url.size()) {
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                        }

                    }

                    @Override
                    public void onLoadingCancelled(String imageUri, View view) {
                        // TODO Auto-generated method stub

                    }
                });
                count++;
            }


        }

    }

    private void updateData(List<KalturaMediaEntry> listEntries) {
        copyEntries = new ArrayList<KalturaMediaEntry>();
        copyEntries.addAll(listEntries);

        if (copyEntries.size() > 0) {
            int sizeListentry = copyEntries.size();

            lastCreatedEntry = copyEntries.get(copyEntries.size() - 1);
            copyEntries.remove(lastCreatedEntry);

        }

        switch (orientation) {

            case Configuration.ORIENTATION_PORTRAIT:
                Log.w(TAG, "start in port");
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                createGridForPort();
                if (listEntries.size() > 0) {
                    ImageLoader();
                }
                break;

            case Configuration.ORIENTATION_LANDSCAPE:
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                if (listEntries.size() > 1) {

                    createGridForLand();
                    Log.w(TAG, "start in land");
                    if (listEntries.size() > 0) {
                        ImageLoader();
                    }


                    break;

                }
        }
    }

    private void processItem(ItemGrid ig, int index, int width, int height) {
        ig.getThumb().getLayoutParams().width = width;
        ig.getThumb().getLayoutParams().height = height;
        ig.getThumb().setScaleType(ImageView.ScaleType.CENTER_CROP);
        ig.setKey(copyEntries.get(index));
    }

    private void processNoElement(ItemGrid ig) {
        ig.getThumb().setVisibility(View.VISIBLE);
        ig.getProgressBar().setVisibility(View.INVISIBLE);

    }

    private void addThumbListener(ItemGrid ig, final int index) {
        ig.getThumb().setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                if (index < copyEntries.size()) {
                    KalturaBaseEntry ent = copyEntries.get(index);
                    getActivityMediator().showInfo(ent.id, "Most Popular", ent.partnerId);
                    Log.w(TAG, "click first" + index);
                }
            }
        });
    }

    //TODO Fixa portrait grid
    private void createGridForPort() {
        Log.w(TAG, "grid for port");

        if (copyEntries.size() > 0) {
            contentPort = new ArrayList<GridForPort>();
            Log.w(TAG, "size: " + copyEntries.size());
            int countConent = copyEntries.size() / 2;
            Log.w(TAG, "countConent: " + countConent);
            int rest = copyEntries.size() % 2;
            Log.w(TAG, "rest: " + rest);

            if (rest != 0) {
                countConent = countConent + 1;
                Log.w(TAG, "countConent: " + countConent);
            }

            //Create countContent contents
            int offset = 0;
            int size = copyEntries.size();

            if (size > 2) {
                Log.w(TAG, "1 offset: " + offset);
                contentPort.add(new GridForPort(TAG, this, offset));
                size = size - 2;
                for (int i = 0; i < countConent - 1; i++) {
                    offset = offset + 2;
                    size = size - 2;
                    Log.w(TAG, "3 offset: " + offset);
                    contentPort.add(new GridForPort(TAG, this, offset));
                }

            } else {
                Log.w(TAG, "2 offset: " + 0);
                contentPort.add(new GridForPort(TAG, this, 0));
            }

            // check display size to figure out what image resolution will be loaded
            DisplayMetrics metrics = new DisplayMetrics();
            display.getMetrics(metrics);
            Point size1 = new Point();
            display.getRealSize(size1);

            int width = size1.x;
            int height = size1.y;


            float scale = (float) size1.x / (float) size1.y;
            //set params
            for (final GridForPort templateContent : contentPort) {
                ll_base.addView(templateContent.getRowGrid());

                if (templateContent.getOffset() < copyEntries.size()) {
                    processItem(templateContent.getLeftItemGrid(), templateContent.getOffset(), size1.x / 2, size1.x / 2);
                } else {
                    Log.w(TAG, "no left element");
                }
                if (templateContent.getOffset() + 1 < copyEntries.size()) {
                    processItem(templateContent.getRightItemGrid(), templateContent.getOffset() + 1, size1.x / 2, size1.x / 2);
                } else {
                    Log.w(TAG, "no right element");
                    processNoElement(templateContent.getRightItemGrid());
                }

                addThumbListener(templateContent.getLeftItemGrid(), templateContent.getOffset());
                addThumbListener(templateContent.getRightItemGrid(), templateContent.getOffset() + 1);
            }
        } else {
            Log.w(TAG, "list size is 0");
        }
    }

    private void createGridForLand() {
        Log.w(TAG, "grid for land");

        if (copyEntries.size() > 0) {
            contentLand = new ArrayList<GridForLand>();
            Log.w(TAG, "size: " + copyEntries.size());
            int countConent = copyEntries.size() / 3;
            Log.w(TAG, "countConent: " + countConent);
            int rest = copyEntries.size() % 3;
            Log.w(TAG, "rest: " + rest);

            if (rest != 0) {
                countConent = countConent + 1;
                Log.w(TAG, "countConent: " + countConent);
            }

            //Create countContent contents
            int offset = 0;
            int size = copyEntries.size();

            if (size > 1) {
                Log.w(TAG, "1 offset: " + offset);
                contentLand.add(new GridForLand(TAG, this, offset));
                size = size - 3;
                for (int i = 0; i < countConent - 1; i++) {
                    offset = offset + 3;
                    size = size - 3;
                    Log.w(TAG, "3 offset: " + offset);
                    contentLand.add(new GridForLand(TAG, this, offset));
                }
            } else {
                Log.w(TAG, "2 offset: " + 0);
                contentLand.add(new GridForLand(TAG, this, 0));
            }

            // check display size to figure out what image resolution will be loaded
            DisplayMetrics metrics = new DisplayMetrics();
            display.getMetrics(metrics);
            Point size1 = new Point();
            display.getRealSize(size1);

            float scale = (float) size1.x / (float) size1.y;
            //set params
            for (final GridForLand templateContent : contentLand) {

                ll_base.addView(templateContent.getRowGrid());

                if (templateContent.getOffset() < copyEntries.size()) {
                    processItem(templateContent.getLeftItemGrid(), templateContent.getOffset(), size1.x / 3, size1.x / 3);


                } else {
                    Log.w(TAG, "no left element");
                }

                if (templateContent.getOffset() + 1 < copyEntries.size()) {
                    processItem(templateContent.getCenterItemGrid(), templateContent.getOffset() + 1, size1.x / 3, size1.x / 3);
                } else {
                    Log.w(TAG, "no center element");
                    processNoElement(templateContent.getCenterItemGrid());
                }

                if (templateContent.getOffset() + 2 < copyEntries.size()) {
                    processItem(templateContent.getRightItemGrid(), templateContent.getOffset() + 2, size1.x / 3, size1.x / 3);

                } else {
                    Log.w(TAG, "no right element");
                    processNoElement(templateContent.getRightItemGrid());
                }

                addThumbListener(templateContent.getLeftItemGrid(), templateContent.getOffset());
                addThumbListener(templateContent.getCenterItemGrid(), templateContent.getOffset() + 1);
                addThumbListener(templateContent.getRightItemGrid(), templateContent.getOffset() + 2);

            }
        } else {
            Log.w(TAG, "list size is 0");
        }
    }

    @Override
    public void update(Observable paramObservable, Object paramObject) {
        updateData((List<KalturaMediaEntry>) paramObject);
    }


    private class DownloadListCatigoriesTask extends AsyncTask<Void, States, List<KalturaMediaEntry>> {

        private String message;

        @Override
        protected List<KalturaMediaEntry> doInBackground(Void... params) {
            // Test for connection
            try {
                if (Utils.checkInternetConnection(getApplicationContext())) {
                    /**
                     * Getting list of all entries category
                     */
                    publishProgress(States.LOADING_DATA);
                    /**
                     * Getting list of all entries category
                     */
                    KalturaMediaEntryFilter filter = new KalturaMediaEntryFilter();
                    filter.mediaTypeEqual = KalturaMediaType.VIDEO;
                    filter.categoriesIdsMatchAnd = Integer.toString(categoryId);
                    listEntries = Media.listAllEntriesByIdCategories(TAG, filter, 1, Media.ENTRIES_MAX_COUNT);
                }
                listCategoriesIsLoaded = true;
                Log.w(TAG, "thread is end");
            } catch (Exception e) {
                message = Utils.handleException(TAG, e);
                publishProgress(States.NO_CONNECTION);
            }
            return listEntries;
        }

        @Override
        protected void onPostExecute(List<KalturaMediaEntry> listCategory) {
            progressDialog.hide();
            if (listEntries.size() != 0) {

                updateData(listEntries);
            }
        }


    }
}

EDIT What am trying to put in is something like this

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putIntArray("ARTICLE_SCROLL_POSITION",
            new int[]{ mScrollView.getScrollX(), mScrollView.getScrollY()});
}

protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    final int[] position = savedInstanceState.getIntArray("ARTICLE_SCROLL_POSITION");
    if(position != null)
        mScrollView.post(new Runnable() {
            public void run() {
                mScrollView.scrollTo(position[0], position[1]);
            }
        });
}

Have trying my other variants also, put to paint the picture.

What I think here is like is that you are trying to set scroll position before ScrollView is positioned by layout so it's size is 0 and setting scroll to any value doesn't have any effect. Try restoring the state in OnPreDrawListener

private static final String ARTICLE_SCROLL_POSITION = "ARTICLE_SCROLL_POSITION";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //... your stuff here

    if (savedInstanceState != null) {
        mScrollView.getViewTreeObserver().setOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                mScrollView.getViewTreeObserver().removeOnPreDrawListener(this);
                mScrollView.setScrollY(savedInstanceState.getInt(ARTICLE_SCROLL_POSITION));
            }
        });
    }
}


@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //I don't think scroll x is ever being non-zero here
    outState.putInt(ARTICLE_SCROLL_POSITION, mScrollView.getScrollY());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM