GVKun编程网logo

android – 如何防止布局的方向更改,而不是整个屏幕/活动(android布局方式)

8

以上就是给各位分享android–如何防止布局的方向更改,而不是整个屏幕/活动,其中也会对android布局方式进行解释,同时本文还将给你拓展Android2.3模拟器方向更改、androidloca

以上就是给各位分享android – 如何防止布局的方向更改,而不是整个屏幕/活动,其中也会对android布局方式进行解释,同时本文还将给你拓展Android 2.3模拟器方向更改、android locale更改方向更改、android – ASyncTask,隐藏片段,保留实例和屏幕方向更改、android – EditText不会自动保存在屏幕方向更改上等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

android – 如何防止布局的方向更改,而不是整个屏幕/活动(android布局方式)

android – 如何防止布局的方向更改,而不是整个屏幕/活动(android布局方式)

我需要一个子布局(可以是任何布局,如FrameLayout或RelativeLayout)来忽略方向更改并始终保持横向方向.但不是它的父母或任何其他兄弟布局/视图,他们应该相应地改变他们的方向.

因此,我不能使用setRequestedOrientation()或android:screenorientation =“landscape”.或者它将锁定整个屏幕或活动的方向.我只需要锁定这个单一的布局.

我的布局XML:

RelativeLayout (Parent)
  TextView
    FrameLayout/RelativeLayout <-- this need to be locked
      FrameLayout
        Button

解决方法

这可能取决于你的意思是“不改变方向”.但是,我认为最好的起点是为不应该改变的部分创建自己的类.所以布局xml现在有两个文件:

main_layout.xml

RelativeLayout (Parent)
    TextView
        MyNonChangingLayout

my_non_changing_layout.xml

RelativeLayout
     FrameLayout
         Button

你创建的地方

MyNonChangingLayout extends FrameLayout {
    MyNonchangingLayout(Context content) {
        super(context);
        myContext = context;
        makeFromXML();
    }

private void makeFromXML() {
    LayoutInflater inflater = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    topView =  inflater.inflate(MyR.layout.my_non_changing_layout,this,false);

    // Get all the sub Views here using topView.findViewById()

    // Do any other initiation of the View you need here

    // Make sure you this otherwise it won''t actually appear!
    super.addView(topView);
}

/*
 * Then,you can override quite a lot of the layout''s calls and
 * enforce behavIoUr on the children. Two examples:
 */

// To specifically catch orientation changes
@Overridge
onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // You Could create the layout here by removing all views and rebuilding them
    // Perhaps by having a two xml layouts,one of which is "90 degrees out" ...
    // If you do make the layot here,make sure you don''t clash with the constructor code!
    switch (newConfig.orientation) {
        case ORIENTATION_LANDSCAPE:
            // Make the layout for this orientation (as per above)
            break;
        case ORIENTATION_PORTRAIT:
            // Make the layout for this orientation (as per above)
            break;
        case ORIENTATION_SQUARE:
            // Make the layout for this orientation (as per above)
            break;
    }
}

//to handle size changes to enforce aspect ratios on children:
@override
protected void onSizeChanged (int w,int h,int oldw,int oldh) {
    super.onSizeChanged(w,h,oldw,oldh);

    int viewWidth = //something I''ve determine
    int viewHeight = //something I''ve determined
    setViewsize(viewToHaveSizedControlled,viewWidth,viewheight);
}

// The post thing means that it doesn''t crash no matter which thread it is
// executed on ...
private void setViewsize(final View v,final int w,final int h) {
    post(new Runnable() {
        public void run() {
            ViewGroup.LayoutParams lp = v.getLayoutParams();
            lp.width = w;
            lp.height = h;
            v.setLayoutParams(lp);
    }});
}

}

然后,您可以很好地执行您想要的任何事情.如果您可以更具体地了解要在子区域上执行的行为,我可能会建议更具体的代码.

你可能想要做的一件事就是保持

Android 2.3模拟器方向更改

Android 2.3模拟器方向更改

我遇到了一个问题,我认为这与模拟器本身有关.我在我的一个活动中将此代码放在onCreate方法的顶部:

Log.d(Const.TAG, "onCreate orientation: " + getRequestedOrientation());

每次我在模拟器中切换方向(通过Ctrl F11和/或Num 7)时,它会打印-1(对应于SCREEN_ORIENTATION_UNSPECIFIED),并且它会陷入横向状态(除非重新启动应用程序,否则不会切换回纵向).

难道我做错了什么?还有其他人有这个问题吗?这是一个严格与2.3仿真器相关的问题,还是出现在设备上(目前是Nexus S)?

解决方法:

这是模拟器的问题.看到:
http://code.google.com/p/android/issues/detail?id=13189

并在stackoverflow上:
why does the gingerbread emulator orientation get stuck in apps?

遗憾的是,10.0 Android SDK(2011年2月发布)未解决此问题.

android locale更改方向更改

android locale更改方向更改

在我的应用程序中,我有两个活动,一个可以旋转到两侧,另一个被锁定在横向模式.

以下是我的清单文件详细信息,其中添加了活动

figChanges="orientation|screenSize|keyboardHidden">
figChanges="orientation|screenSize|keyboardHidden">

在我的登录活动中使用微调器我正在更改区域设置并更新整个编辑文本和按钮文本.
在按钮单击操作中,我正在更新UI视图,当我旋转设备时,英语区域设置在更新的视图上设置
这是我的整个代码

public class LoginActivity extends Activity 
{
    Locale locale = null;
    Spinner langSpinner;
    private SharedPreferences langPrefs;
    String langSelected = "";
    int langPosition = 0;

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

        langPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        langSelected = langPrefs.getString(langPrefKey,"");
        langPosition = langPrefs.getInt(langPosKey,0);

        langSpinner = (Spinner)this.findViewById(R.id.lanuage_spinner1);
        langSpinner.setSelection(langPosition);
        langSpinner.setonItemSelectedListener(new AdapterView.OnItemSelectedListener() 
        {
            @Override
            public void onItemSelected(AdapterViewnesE;
                }               
                else if (pos == 3)
                {
                    langSelected ="zh-rTW";
                    locale = Locale.TradITIONAL_CHInesE;
                }
                changeLang(langSelected,pos);
            }
            @Override
            public void onnothingSelected(AdapterViewodo Auto-generated method stub

            }   
        });

        btnLogin = (Button) this.findViewById(R.id.LoginButton);
        btnLogin.setonClickListener(new ButtonClickListener());
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        this.finish();
    }

    @Override
    protected void onDestroy() 
    {
        super.onDestroy();
        this.finish();
    }

    public class ButtonClickListener implements OnClickListener {
        public void onClick(View v) {
                    final LoginTask validateTask = new LoginTask(context,usernameField.getText().toString(),passwordField.getText().toString());
                    validateTask.execute();
                }

                // Hide the keyboard
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(passwordField.getwindowToken(),0);
    }

    public class LoginTask extends AsyncTaskarams) {
            try 
            {
                return HTTPHelper.LoginTaskData(this.context,username,password);
            }
            catch (Exception e) 
            {
                exception = e;
                Log.e(TAG,"Login Task Error",e);
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) 
        {
            super.onPostExecute(result);
            Log.e(TAG,"LoginTask: " + result);
            if (result.equals("true")) 
            {
                // moves to next activity
            }
            else if (result.equals("false"))
            {
                //showing an alert textview with selected language text
            }
        }
    }

    public void changeLang(String lang,int pos)
    {
        if (lang.length() != 0)
        {       
            saveLocale(lang,pos,locale);
            android.content.res.Configuration config = new android.content.res.Configuration();
            config.locale = locale;
            Locale.setDefault(locale);
            getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getdisplayMetrics());
            updateTexts();
        }
    }

    public void saveLocale(String lang,Locale locale)
    {
        SharedPreferences.Editor editor1 = langPrefs.edit();
        editor1.remove(langPrefKey);
        editor1.remove(langPosKey);
        editor1.commit();

        SharedPreferences.Editor editor = langPrefs.edit();
        editor.putString(langPrefKey,lang);
        editor.putInt(langPosKey,pos);
        editor.commit();

        langSelected = langPrefs.getString(langPrefKey,0);
    }

    private void updateTexts()
    {
        // here i will once again set all textview String values,it changes to the selected language
    }

    @Override
    public void onConfigurationChanged(android.content.res.Configuration newConfig) 
    {
        super.onConfigurationChanged(newConfig);
        if (locale != null){
            newConfig.locale = locale;
            Locale.setDefault(locale);
            getBaseContext().getResources().updateConfiguration(newConfig,getBaseContext().getResources().getdisplayMetrics());
        }
    }
}
最佳答案
如果我理解正确,问题是当你切换屏幕方向时手机的语言环境会恢复,尽管你的AndroidManifest.xml中有android:configChanges =“orientation | screenSize | keyboardHidden”.如果我在你身边,我会从不同的角度来处理这个问题.我会摆脱android:configChanges,当方向改变时,让android重新启动Activity.然后我将使用onSaveInstanceState对来保存用户在Spinner中选择的Locale.再次调用onCreate时,由于方向更改而因为包不为空而调用,因此请读取存储的Locale并重新启动,然后再次更新配置.例如.

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putSerializable("LOCALE",locale);
    super.onSaveInstanceState(savedInstanceState);
}

@Override
public void onCreate(Bundle savedInstanceState)  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loginscreen);
    if (savedInstanceState != null) {
        locale = (Locale) savedInstanceState.getSerializable("LOCALE");
        if (locale != null) {
           // update the configuration 
        }
    }

android – ASyncTask,隐藏片段,保留实例和屏幕方向更改

android – ASyncTask,隐藏片段,保留实例和屏幕方向更改

我的设置如下.

我有一个从我的Activity调用的FragmentPagerAdapter,它加载了两个片段.这是在onCreate中设置的.

在onResume中,我调用ASyncTask从数据库加载数据,然后通过加载数据监听器在我的活动onLoadComplete中调用回调.

    @Override
public void onl oadComplete(JSONArray data) {
    // Todo Auto-generated method stub


    LocalFragment fragmentB = (LocalFragment)getSupportFragmentManager().findFragmentByTag(ListTag);
    fragmentB.setList(data);

    LMapFragment fragmentA = (LMapFragment)getSupportFragmentManager().findFragmentByTag(MapTag);

    GoogleMap our_map = fragmentA.getMap();
    fragmentA.plotP(myLocation,data);

}

片段由寻呼机初始化,并且在每个片段代码中,我设置相应的标签,例如在LocalFragment中

    @Override
public void onAttach(Activity activity) {
    // Todo Auto-generated method stub
    super.onAttach(activity);

    String mytag = getTag();



        ((PagerTest) activity).setListTag(mytag);
        Log.d("what",mytag);


}

这允许我访问片段,调用其中填充列表或填充地图的函数.有用.

我现在要做的是考虑屏幕方向的变化.如果ASyncTask正在运行时方向已更改,则应用程序崩溃.

正如这里建议的:Hidden Fragments我一直在尝试实现一个隐藏的片段,它保存了我的ASyncTask的状态.所以我所做的就是设置它,所以在我的Activity的onResume中调用一个函数

    static LoadDataFromURL the_data = null;
static JSONArray pub_data = null;
private static final String TAG = "RetainFragment";

public RetainFragment() {}

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {

    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
    if (fragment == null) {
        fragment = new RetainFragment();
        fm.beginTransaction().add(fragment, TAG).commit(); // add this
    }
    return fragment;
}

这基本上保存了我的数据.

基本上这意味着,如果我旋转我的屏幕,我不会再次调用我的ASyncTask ..屏幕只是旋转..它完美地工作.

但是,如果我返回主菜单然后再次单击活动,屏幕将返回空白(但不会崩溃).我的理解是数据作为片段中的对象保留,但重新重新加载活动时,需要再次设置数据.需要调用I.E onl oadComplete来填充列表/映射.

所以我总结说,如果最初在ASyncTask完成之后我将返回的数据保存在我的隐藏片段onRetainInstance中,那么我可以简单地调用onLoadComplete并传递它.

问题是,在这种情况下,似乎尚未调用片段,因此标记为null,并且在onLoadComplete中调用回调会使应用程序崩溃.

多年来我一直在为此而奋斗.

我的ASyncTask是一个单独的类:LoadDataFromURL
我想要实现的目标如下 – 一个fragmentviewpager,在屏幕上旋转ASyncTask保留在旋转/附加到新活动,如果它已完成,它不应该再次运行..

任何人都可以建议.

非常感谢

编辑

将我的秘密片段中的变量更改为公共变量后,所有内容似乎都聚集在一起.但是因为我不是100%确定如何/何时调用事物,我不完全理解为什么它起作用..

所以..我调用findOrCreateRetainFragment,它或者创建一个新的’secret’片段或者返回当前实例.

如果它返回当前实例,我不会再次调用我的异步任务.如果不是,我调用我的asynctask并加载数据.

使用此设置,当我加载活动并旋转屏幕时,它会按预期旋转.

现在,当我返回主菜单然后再次单击活动时,它会调用异步任务.

我的理解是,在旋转时,不会再次调用异步任务,并且viewpager以某种方式保存片段.

另一方面,当我回去时,我的活动被破坏,就像我的秘密片段一样,当我再次点击它时,它会加载数据.这基本上就是我想要的……

我理解正确吗?

谢谢

解决方法:

这里有一些你遇到的问题(我认为).

首先,回调崩溃的原因是因为它们附加到屏幕方向和/或活动推送后不再“存在”的旧活动.如果使用onAttach()将回调附加到片段,则必须使用onDetach()在从活动中删除片段时分离该回调.然后,每当您调用回调时,请检查null,以便不将数据发送到死对象.

基本上,你在这里尝试使用的逻辑是:

>开始活动.
>检查您的碎片是否存在.如果是的话,抓住它.否则,创造它.
>检索数据是否存在.如果没有,请等待回调.

由于回调的性质(取决于您的实现),在事件触发之前您不会收到数据.但是,如果Activity已经消失并且事件已经触发,则不会执行回调.因此,您必须手动检索数据.使用setRetainInstance()时,将其视为从您的Activity中分离出来的实体是有帮助的.只要您不弹出当前活动或推送新活动,它就会存在.但是,当屏幕方向更改时,您的当前活动将被销毁,而片段则不会.因此,Fragment不应该依赖于Activity的存在.

您可能希望查看的问题的更优雅的解决方案是实现Android Loader API.加载程序是由系统处理的方便工具,其工作方式大致相同,但与异步检索数据更加协调.他们以同样的方式有效地工作.您只需启动您的加载器和系统,如果它不存在则创建一个或重新使用已存在的系统.配置更改后,LoaderManager将保留在系统中.

编辑:

要回答你的编辑,我想我会解释发生了什么.这是令人费解的,所以只要告诉我是否需要澄清.

从技术上讲,碎片不是您当前运行的Activity的一部分.创建Fragment的实例时,必须在FragmentManager上调用beginTransation()和commit(). FragmentManager是一个存在于应用程序领域内的单例. FragmentManager会为您保留Fragment的实例.然后FragmentManager将Fragment附加到您的Activity(请参阅onAttach()). Fragment然后存在于FragmentManager中,这就是为什么你永远不必在你的应用程序中持有对它的引用.您可以调用findFragmentByTag / Id()来检索它.

在正常情况下,当您的Activity被销毁时,FragmentManager将分离Fragment的实例(请参阅onDetach())并让它继续. Java垃圾收集器将检测到没有对Fragment的引用,并将清理它.

当你调用setRetainInstace()时,你告诉FragmentManager保持它.因此,当您的Activity在配置更改时被销毁时,FragmentManager将保留Fragment的引用.因此,重建Activity时,可以调用findFragmentByTag / Id()来检索最后一个实例.只要它没有保留最后一个Activity的任何上下文,就不应该有任何问题.

传统上,人们会用它来保持对长期数据的引用(就像你一样)或保持连接套接字打开,这样手机翻转就不会删除它.

您的ViewPager与此无关.它如何检索Fragments完全取决于您如何实现它附加到的Adapter.通常,保留的片段本身没有视图,因为视图保存了创建它们的活动的上下文数据.您基本上只想使它成为一个数据桶,以保持视图从它们被拉出时的数据被夸大了.

android – EditText不会自动保存在屏幕方向更改上

android – EditText不会自动保存在屏幕方向更改上

我读到当应用程序即将停止或终止时,Android会自动保存EditText对象的内容.但是,在我的应用程序中,当屏幕方向更改时,EditText的内容将丢失.

这是正常的行为吗?那么我是否必须使用onSaveInstanceState / onRestoreInstanceState手动保存/恢复其内容?或者是否有更简单的方法告诉Android保存它还原它?

编辑:

我以编程方式创建EditText对象,而不是XML.事实证明这与问题有关(见下面接受的答案).

解决方法:

这不是正常行为.

首先,确保在布局XML中为您的EditText控件分配了ID.

编辑1:它只需要一个ID,句点.如果您以编程方式执行此操作,除非它具有ID,否则它将丢失状态.

因此,使用它作为快速和脏的例子:

    // Find my layout
    LinearLayout mLinearLayout = (LinearLayout) findViewById(R.id.ll1);
    // Add a new EditText with default text of "test"
    EditText testText = new EditText(this.getApplicationContext());
    testText.setText("test");


    // This line is the key; without it, any additional text changes will 
    // be lost on rotation. Try it with and without the setId, text will revert
    // to just "test" when you rotate.

    testText.setId(100); 

    // Add your new EditText to the view.
    mLinearLayout.addView(testText);

这将解决您的问题.

如果失败,您需要自己保存和恢复状态.

像这样覆盖onSaveInstanceState:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("textKey", mEditText.getText().toString());
}

然后在OnCreate中恢复:

public void onCreate(Bundle savedInstanceState) {
    if(savedInstanceState != null)
    {
        mEditText.setText(savedInstanceState.getString("textKey"));
    }
}

另外,请不要使用android:configChanges =“orientation”来尝试实现这一点,这是错误的方法.

关于android – 如何防止布局的方向更改,而不是整个屏幕/活动android布局方式的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Android 2.3模拟器方向更改、android locale更改方向更改、android – ASyncTask,隐藏片段,保留实例和屏幕方向更改、android – EditText不会自动保存在屏幕方向更改上的相关信息,请在本站寻找。

本文标签: