0

基本的

  • 私は2つのレイアウト activity_main_layout.xml と layout2.xml を持っています

  • getActionbar().newTab()メソッドを使用して、ActionBar に 2 つのタブを作成しました。

  • activity_main_layout.xml (最初のタブ)にボタンとテキスト ボックス ( EditText ) があります。

  • ボタンとテキスト ボックスの両方に動的に入力されたテキスト「Test 123」があります。

  • タブ 2 が選択されている場合、setContentView(R.layout.layout2) というコード ステートメントがあり 2 番目のレイアウトが表示され、タブ 1 についても同様です: setContentView(R.layout.activity_main)

    タブ 1 を再度選択すると、動的に入力されたテキスト "Test 123" が消え、設計時に XML で設定されたテキストが残ります。そのため、現在、タブが選択される前に Buttons と EditTexts の内容を保存し、選択後にそれらを復元する必要があります。

これが正しい方法だとは思いません。画面が回転したときにコンテンツを保存するために、すでにonSaveInstanceState()およびonRestoreInstanceState()savedInstanceState.putXX および getXXなどで利用していますが、現在の問題では機能していないようです。私はこれまで答えを見つけることができませんでした。誰か手がかりを教えてください。任意の応答をいただければ幸いです。

4

4 に答える 4

0

これが私が持っているコードです:

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<Button
    android:id="@+id/btn_One"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_weight="1.70"
    android:text="Activity_main.xml - Design Time Text"
    android:textSize="12sp"
    android:onClick="btnOne_OnClick"
    android:textStyle="normal" />

layout2.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

            <Button
                android:id="@+id/btn_Two"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Layout2.xml - Design Time Text"
                android:textSize="12sp"
                android:textStyle="normal" />

メインコードでは、コメントに注意してください:

public class MainActivity extends Activity implements ActionBar.TabListener {

ActionBar.Tab Tab_1 = null, Tab_2 = null;
Button btn_One = null, btnTwo = null;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ///////////////////////////////////////////////////////////////////
    ActionBar actionbar = (ActionBar) getActionBar();
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    Tab_1 = actionbar.newTab().setText("Tab 1");
    Tab_2 = actionbar.newTab().setText("Tab 2");

    Tab_1.setTag(1);
    Tab_2.setTag(2);


    Tab_1.setTabListener(this);
    Tab_2.setTabListener(this);        

    actionbar.addTab(Tab_1);
    actionbar.addTab(Tab_2);
    ///////////////////////////////////////////////////////////////////

    btn_One = (Button)this.findViewById(R.id.btn_One);
}


public void btnOne_OnClick(View v) {
    ((Button)v).setText("Clicked");
    btn_One = ((Button)v);
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {}

// Here is what the problem is:
// After you click btn_one, the text changes to "Clicked" - good! - however
// after Tab 1 gets reselected, the text off btn_One (btn_One) gets reset back to the one
// set in design time: "Activity_main.xml - Design Time Text", so the "Clicked" text disappears
// The interesting thing is, when you rotate the screen, the text gets re-initialized to "Clicked" and that's
// because of onRestoreInstanceState(). So it looks like when a tab gets reselected, the design time screen
// gets re-drawn and onRestoreInstanceState doesn't get recalled.
// My "workaround" for the above issue would be to create a global 
// "Bundle" poiner and pass the address of the one from onSaveInstanceState(Bundle savedInstanceState)
// to the global Bundle pointer and then call onRestoreInstanceState(*the_global_bundle_pointer*) 
// when a tab gets reselected so that it restores the state.

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {

    int selectedTab = (Integer) tab.getTag();

    if (selectedTab == 1) this.setContentView(R.layout.activity_main);
    if (selectedTab == 2) this.setContentView(R.layout.layout2);

}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
  if (btn_One != null) savedInstanceState.putString("btn_One", btn_One.getText().toString());

  super.onSaveInstanceState(savedInstanceState);  
}  

// When the instance is restored, reload all data
@Override  
public void onRestoreInstanceState(Bundle savedInstanceState) 
{  
    super.onRestoreInstanceState(savedInstanceState);

    if (btn_One != null) btn_One.setText(savedInstanceState.getString("btn_One").toString());  
}       

}

また、私が2つのタブを言う理由は、私が解決しようとしていることを人々が理解できるように、可能な限り簡単な方法で問題を示すことができるようにするためです。私の実際のプロジェクトでは、2つ以上のタブを使用しています。

上記の問題に対する私の「回避策」は、グローバルな「バンドル」ポインターを作成し、そのアドレスをonSaveInstanceState(Bundle savedInstanceState)からグローバルバンドルポインターに渡し、タブが再選択されたときにonRestoreInstanceState(* the_global_bundle_pointer *)を呼び出すことです。状態を復元します。

どう思いますか?

于 2012-12-30T21:49:02.703 に答える
0

「マスターから学ぶ」状態とは別に、この構造を構築するためのより良い方法があります (ページ アダプター/ページ ビューアー/フラグメント...)。バンドルの saveInstanceState を正しく使用すると、正常に動作するはずです。

あなたのコードを投稿できますか?

コードを見た後に編集:

おそらく、代わりに onCreate() で Bundle savedInstanceState を確認する必要があります。これはちょっと似てる

    @Override
    public void onCreate(Bundle savedInstanceState) {
         [...]
     if(savedInstanceState != null){
       //restore your stuff from the Bundle
      }else{
       // there is nothing to restore, so (down)load your data.
       }
    }

https://stackoverflow.com/a/6722854/1868384で見つけることができる詳細な説明

于 2012-12-30T14:04:20.410 に答える
0

あなたがた両方に感謝します。Android では、新しいコンテンツ レイアウトがアクティビティに設定されると、テキスト ボックス、以前のレイアウトのボタンなどの既存の UI 要素が使用できなくなるため、それらにアクセスしようとするとアクセス違反が発生することが判明しました。コンテンツ レイアウトを設定すると、UI 要素がゼロから再構築されたように見えるため、すべてのデータが失われます。これは私が個人的に気づいたことであり、確かにデフォルトの動作のようです。この動作を変更できるかどうかはわかりません。

独自の「カスタム ソリューション」を作成しました。私がしたことは、たくさんのデータ メンバーを含む新しいクラスを作成することだけです。タブがクリックされたときやデバイスが回転したとき (onSaveInstance) にレイアウトを適用するときなど、アクティビティに新しいコンテンツを設定するたびに、このクラスから値を保存/復元します。以前は Bundle putInt、putString、putParcelable などを使用していましたが、別のルートを取ることにしました。私のやり方では、私は管理下にあり、コードで何が起こっているかを正確に知っています.

于 2013-01-01T07:51:41.833 に答える
0

タブが 2 つしかない場合は、pageadapter を使用しませんか? モバイルの位置を変更するか、アプリを終了するまで、情報が失われることはありません。

基本的にはそのようなものです(私のコードの1つのスクラッチをあなたに置きます).

注: パケット ShelockActivity を使用して、android > 2.0 のタブメニューを表示します。

メインクラス:

public class MainClass extends SherlockActivity implements ActionBar.TabListener {
ViewPager myPager;
AdapterClass adapter;
Context con = null;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    con = this.getBaseContext();
    //Restore info in case flip mobile      
    final Myobject data = (Myobject) getLastNonConfigurationInstance();     
    Bundle extras = getIntent().getExtras(); 

   //Tab bar
    getSupportActionBar().setDisplayShowHomeEnabled(false);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    //loop for add more
    ActionBar.Tab tab = getSupportActionBar().newTab();
    tab.setText("text tab");

            if (data != null) {
            getdatatoyourobject(data);
        }
    myPager = (ViewPager) findViewById(R.id.panelpager);    
    myPager.setAdapter(adapter);    
    myPager.setOnPageChangeListener(new OnPageChangeListener() {
          @Override
          public void onPageSelected(int index) {
              getSupportActionBar().setSelectedNavigationItem(index);            
          }
    adapter = new AdapterClass(Parameters for your adapterclass);


        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub

        }

    });
}
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub
        myPager.setCurrentItem(tab.getPosition(),true);         
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub

}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub

}
@Override
public Object onRetainNonConfigurationInstance() {
    final Myobject a = new Myobject();
    return a;       
}

public class Myobject {
    Type variable = adapter.variable; //do for all variables to restore     
}

public void getdatatoyourobject(Myobject a){
    adapter.variable = a.variable;    //do for all variables to restore     
}
}

アダプタークラス:

  public class Adapterclass extends PagerAdapter {

  public int getCount() {
      return 2; //NUMBER OF PAGES
  }  

  public Adapterclass () {      
  }  

 public View view = null; //create rest of variables to restore as public

 public Object instantiateItem(View collection, int position) {

  LayoutInflater inflater = (LayoutInflater) collection.getContext()
          .getSystemService(Context.LAYOUT_INFLATER_SERVICE);


  switch (position) {
  case 0:
      view = inflater.inflate(R.layout.page1, null);
       //bla bla bla
       break;
//do more cases (pages)
  }
      ((ViewPager) collection).addView(view, 0);

     return view;
 }

 @Override
 public void destroyItem(View arg0, int arg1, Object arg2) {
      ((ViewPager) arg0).removeView((View) arg2);

  }

  @Override
  public boolean isViewFromObject(View arg0, Object arg1) {
      return arg0 == ((View) arg1);

  }

  @Override
  public Parcelable saveState() {
      return null;
  }
}

メイン.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">

<android.support.v4.view.ViewPager
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/panelpager"/>

于 2012-12-30T13:38:09.413 に答える