开发者

Orientation change does not redraw layout completely

This is a Major Edit on my previous question

I'm creating a custom (composite) component named OneLineSeeker that consists of a TextView and a SeekBar. When I have multiple OneLineSeekers declared in a layout, they don't retain their state on configuration change. All seeker thumbs assume the same position (the position of the last OneLineSeeker) on configuration change. If I don't use the custom component and use only SeekBars individually (uncomment //a() in main activity), they will retain their individual positions on configuration change. Can anyone help?

src files

A_seekbarsActivity.java

package com.an;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;

public class A_seekbarsActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //a();
    }

    void a() {

        setContentView(R.layout.main_1);

        Butto开发者_运维技巧n b = (Button) findViewById(R.id.button1);
        b.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                SeekBar sb = (SeekBar) findViewById(R.id.seekBar1);
                if(sb.getProgress() > 50) sb.setProgress(0);
                else sb.incrementProgressBy(5);

            }
        });
    }
}

OneLineSeeker.java

package com.an;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class OneLineSeeker extends LinearLayout {

    public OneLineSeeker(Context context, AttributeSet attrs) {
        super(context, attrs);

        View ols = LayoutInflater.from(context).inflate(R.layout.one_line_seeker, this, true);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OneLineSeeker, 0, 0);

        String text = array.getString(R.styleable.OneLineSeeker_name);
        if (text != null) 
            ((TextView) ols.findViewById(R.id.name)).setText(text);

        array.recycle();

    }
}

res/layout files

main_1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <SeekBar android:id="@+id/seekBar1" android:layout_height="wrap_content" android:layout_width="match_parent"></SeekBar>
    <SeekBar android:id="@+id/seekBar2" android:layout_height="wrap_content" android:layout_width="match_parent"></SeekBar>
    <SeekBar android:id="@+id/seekBar3" android:layout_height="wrap_content" android:layout_width="match_parent"></SeekBar>
    <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:oneLineSeeker="http://schemas.android.com/apk/res/com.an"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

    <com.an.OneLineSeeker 
     android:id="@+id/s1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     oneLineSeeker:name="1"
     />

    <com.an.OneLineSeeker 
     android:id="@+id/s2"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     oneLineSeeker:name="2"
     />

    <com.an.OneLineSeeker 
     android:id="@+id/s3"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     oneLineSeeker:name='3'
     />     

</LinearLayout>

one_line_seeker.xml

<?xml version="1.0" encoding="utf-8"?>
<merge
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 >

    <TextView 
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:id='@+id/name'
     android:text='name'
     />

    <SeekBar
     android:id='@+id/seekbar'
     android:layout_width="match_parent" 
     android:layout_height="match_parent"
     /> 

</merge>

res/values files

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="OneLineSeeker">
        <attr name="name" format="string"/>
    </declare-styleable>
</resources>


Its not supposed to reset its position to zero. This is actually a feature. When view has id associated with, it usually saves and the restores its state on configuration changes.

If you don't want specific view to save state on configuration change, you can remove android:id from view's entry in layout (but you won't be able to control that view then). Another alternative is to extend ProgressBar and disable its ability to restore state.

The last one option is the easiest one: override onRestoreInstanceState() and reset state there:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
    super.onRestoreInstanceState(savedInstanceState);
    bar.setProgress(0);
}

But I would strongly recommend not resetting view state. After all the whole idea of restoring state on configuration change is to make user think as if nothing really changed. And you need to have very strong reasons to disable this behavior.


In that u have to define Orientation Change Methods.....

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    onCreate(null);
}

Try this Code may u get any Help.....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜