【问题标题】:Update layout after writing SharedPreferences?编写 SharedPreferences 后更新布局?
【发布时间】:2019-01-28 17:50:42
【问题描述】:

我在这里的第一个主题-如果文本格式不好,请见谅。

我使用 Android Studio 3.1.3 API27 并为智能手机开发一个应用程序。

该应用目前由 1 个活动(分为 3 个片段)、第二个活动和 5 个 xml 文件组成。

通过使用 ViewPager,我可以浏览 3 个片段。

第二个片段(中间片段)包含 2 个按钮,每个按钮打开第二个活动,其中包含许多颜色按钮。

当点击颜色按钮时,我可以改变第一个片段的背景颜色。

选择颜色后,第二个活动关闭,我回到活动 1 -> 片段2。

它有效,但问题是我总是必须滑动到第三个片段, 然后回到第 2 次再到第 1 次。

如果我不这样做,片段 1 的颜色将保持旧的颜色。

现在我正在寻找一种方法来更新片段 1 的布局,只要我按下活动 2 的颜色按钮。

我已经试过了:

  • 在编写 SharedPreferences (Activity2) 时,我使用 editor.apply() 而不是 editor.commit()
  • 在读取 SharedPreferences (Activity1 -> Fragment1) 时,我使用 Context.MODE_MULTI_PROCESS 而不是 Context.MODE_PRIVATE
  • 使用 viewpage.setOffscreenPageLimit(0);在我的公共 void SetUpViewPager(ViewPager viewpage) 方法的 MainActivity 中。

但没有任何帮助。

看起来是这样的:

MainActivity.java(活动一):

import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    import java.util.ArrayList;
    import java.util.List;

    public class MainActivity extends AppCompatActivity
    {
        ViewPager vp;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ViewPager vp = findViewById(R.id.vp);
            SetUpViewPager(vp);
        }
        public void SetUpViewPager(ViewPager viewpage)
        {
            MyViewPagerAdapter Adapter = new MyViewPagerAdapter(getSupportFragmentManager());
            Adapter.AddPageFragment(new Page_1(), "Page 1");
            Adapter.AddPageFragment(new Page_2(), "Page 2");
            Adapter.AddPageFragment(new Page_3(), "Page 3");
            viewpage.setOffscreenPageLimit(0);
            viewpage.setAdapter(Adapter);
        }
        public class MyViewPagerAdapter extends FragmentPagerAdapter
        {
            private List<Fragment> MyFragment = new ArrayList<>();
            private List<String> MyPageTitle = new ArrayList<>();

            public MyViewPagerAdapter(FragmentManager manager)
            {
                super(manager);
            }
            public void AddPageFragment(Fragment Frag, String Title)
            {
                MyFragment.add(Frag);
                MyPageTitle.add(Title);
            }
            @Override
            public Fragment getItem(int i)
            {
                return MyFragment.get(i);
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position)
            {
                return MyPageTitle.get(position);
            }

            @Override
            public int getCount()
            {
                return 3;
            }
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
        @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            int id = item.getItemId();

            if (id == R.id.action_settings)
            {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }

Page_1.java(活动 1 -> 片段 1):

import android.content.Context;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.constraint.ConstraintLayout;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    import static android.content.Context.MODE_PRIVATE;

    public class Page_1 extends Fragment
    {
        int backgroundColorLeft, backgroundColorRight, textColorLeft, textColorRight; // Variables for SharedPreferences

        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View PageOne = inflater.inflate(R.layout.page1, container, false); // Link view to layout?
            return PageOne;
        }

        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState)
        {
            SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", Context.MODE_MULTI_PROCESS); // Load saved shared file
            backgroundColorLeft = prefs.getInt("backgroundColorLeft", backgroundColorLeft); // Load saved background color for left layout
            textColorLeft = prefs.getInt("textColorLeft", textColorLeft); // Load saved text color for left layout
            backgroundColorRight = prefs.getInt("backgroundColorRight", backgroundColorRight); // Load saved background color for right layout
            textColorRight = prefs.getInt("textColorRight", textColorRight); // Load saved text color for right layout

            RelativeLayout relLayoutLeft = getActivity().findViewById(R.id.rel_layout_left); // Link variable to ID of left layout
            relLayoutLeft.setBackgroundColor(backgroundColorLeft); // Change background color of left layout
            TextView tvLeft = getActivity().findViewById(R.id.tv_left); // Link variable to ID
            tvLeft.setTextColor(textColorLeft); // Change text color of left layout

            RelativeLayout relLayoutRight = getActivity().findViewById(R.id.rel_layout_right); // Link variable to ID of right layout
            relLayoutRight.setBackgroundColor(backgroundColorRight); // Change background color of right layout
            TextView tvRight = getActivity().findViewById(R.id.tv_right); // Link variable to ID
            tvRight.setTextColor(textColorRight); // Change text color of right layout
            super.onActivityCreated(savedInstanceState);
        }
    }

Page_2.java(活动 1 -> 片段 2):

package com.example.konstantin.clipcodes_swiping;
    import android.content.Context;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.RelativeLayout;

    import static android.content.Context.MODE_PRIVATE;

    public class Page_2 extends Fragment
    {
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View PageTwo = inflater.inflate(R.layout.page2, container, false);
            Button buttonLeft = PageTwo.findViewById(R.id.button_left);  // Link variable to ID of left button
            buttonLeft.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    int pos = 1; // Set position to left
                    setPosition(pos); // Load setColor method and send 2 color values
                }
            });
            Button buttonRight = PageTwo.findViewById(R.id.button_right);  // Link variable to ID of right button
            buttonRight.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    int pos = 2; // Set position to right
                    setPosition(pos); // Load setColor method and send 2 color values
                }
            });
            return PageTwo;
        }
        public void setPosition (int pos) // Start second activity to choose colors
        {
            Intent intentPos = new Intent(getActivity(), Page_4_Colors.class); // Create intent for current Activity and target activity
            SharedPreferences prefs = getActivity().getSharedPreferences("bgColor", Context.MODE_MULTI_PROCESS); // Create new SharedPreferences instance
            SharedPreferences.Editor editor = prefs.edit(); // Assign variable to editor function
            editor.putInt("position", pos); // Write selected position (int) inside of editor
            editor.apply(); // Save values, close process
            getActivity().startActivity(intentPos); // Start second activity
        }
    }

Page_3.java(活动 1 -> 片段 3):

        import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;

    public class Page_3 extends Fragment
    {
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View PageThree = inflater.inflate(R.layout.page3, container, false);
            return PageThree;
        }
    }

Page_4_Colors.java(活动 2):

        import android.app.Activity;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;

    public class Page_4_Colors extends Activity
    {
        int pos;
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.page4_colors);
            SharedPreferences prefs = getSharedPreferences("bgColor", MODE_MULTI_PROCESS); // Load saved shared file
            pos = prefs.getInt("position", pos); // Load saved position (int)
            Log.wtf("Position", String.valueOf(pos)); // Show pos value in Log
            Button buttonWhite = findViewById(R.id.button_white);
            buttonWhite.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    setColor(getResources().getColor(R.color.white), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
                }
            });
            Button buttonYellow = findViewById(R.id.button_yellow);
            buttonYellow.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    setColor(getResources().getColor(R.color.yellow), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
                }
            });
            Button buttonOrange = findViewById(R.id.button_orange);
            buttonOrange.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    setColor(getResources().getColor(R.color.orange), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
                }
            });
            Button buttonRed = findViewById(R.id.button_red);
            buttonRed.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    setColor(getResources().getColor(R.color.red), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
                }
            });
            Button buttonGreen = findViewById(R.id.button_green);
            buttonGreen.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    setColor(getResources().getColor(R.color.green), getResources().getColor(R.color.black)); // Load setColor method and send 2 color values
                }
            });
            Button buttonBlue = findViewById(R.id.button_blue);
            buttonBlue.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    setColor(getResources().getColor(R.color.blue), getResources().getColor(R.color.white)); // Load setColor method and send 2 color values
                }
            });
        }
        public void setColor (int backgroundColor, int textColor) // Write color values into SharedPreferences
        {
            SharedPreferences prefs = getSharedPreferences("bgColor", MODE_MULTI_PROCESS); // Create new SharedPreferences instance
            SharedPreferences.Editor editor = prefs.edit(); // Assign variable to editor function
            if (pos == 1)
            {
                editor.putInt("backgroundColorLeft", backgroundColor); // Write background color (int) inside of editor
                editor.putInt("textColorLeft", textColor); // Write text color (int) inside of editor
            }
            if (pos == 2)
            {
                editor.putInt("backgroundColorRight", backgroundColor); // Write background color (int) inside of editor
                editor.putInt("textColorRight", textColor); // Write text color (int) inside of editor
            }
            editor.apply(); // Save values, close process
            this.finish(); // Close this activity
        }
    }

感谢您的帮助!

【问题讨论】:

  • 所以你想在改变颜色的时候直接更新颜色?
  • 在 onActivityCreated 中编写的第一个片段中剪切粘贴到 onResume()
  • 抱歉@VishalThakkar,我写答案时没有阅读您的回复。
  • 哦,哇,居然解决了!谢谢!我什至需要 onActivityCreated 吗?

标签: java android android-fragments layout refresh


【解决方案1】:

您可以在 onResume() 方法中更新每个片段的 UI(或至少与颜色相关的部分),因此,当您从第二个活动返回时,它会刷新。

【讨论】:

  • 谢谢。我假设在这种情况下我应该在 Page_2.java 中添加 onResume?所以每次我关闭 Acitivity 2(并自动返回到 Page_2)时,它都会执行 onResume 方法。我做了一个测试: Log.wtf("test", "Fragment2 loaded");是的,它奏效了。但是,我不知道我必须在这个方法中发布什么。
  • 你在 onActivityCreated 中写的,就像@Vishal Thakkar 所说的
【解决方案2】:

使用EventBus

在Page_1 onStop()onStart()中注销并注册EventBus

 EventBus.getDefault().unregister(this)

 EventBus.getDefault().register(this)

并用它来发布价值

EventBus.getDefault().post(new MessageEvent("Change Color"));

这个函数会处理MessageEvent

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    //change the color here
    //add this function in Page_1 
}

当你更新颜色的值时。放入 MessageEvent documentation

【讨论】:

    【解决方案3】:

    当 Fragment 可见时(即 ViewPager 中的选定页面),它的 setUserVisibleHint() 方法被调用。您可以在 Fragment 中覆盖该方法并使用它来触发刷新。

     @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            if(isVisibleToUser){
             //you can check if the color is changed then refresh the fragment if not then don't do anything
             //here you should refresh your fragment , this will called every time you
             //view this fragment in all cases even if you didn't move to the 
             //third tab 
            }
        }
    

    如何刷新片段

        Fragment currentFragment = getFragmentManager().findFragmentByTag("YourFragmentTag");
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        fragmentTransaction.detach(currentFragment);
        fragmentTransaction.attach(currentFragment);
        fragmentTransaction.commit();
    

    【讨论】:

    • 这可行,但是当 viewpager 完成滚动时将调用该方法。所以他会在滚动完成之前看到旧颜色,然后更改颜色:)
    • 即使他在第二个选项卡中然后移动到第一个或第三个到第一个,每次他转到片段时都会调用此方法,所以他不会看到旧颜色尝试实现它....我的意思是,无论他是否完成滚动或他在哪里(关于第二个三分之一的标签位置),每次他访问片段时都会调用此方法
    • 你是对的。但他不应该把代码放在 if(isVisibleToUser) 中,只有在片段可见时才会调用。
    • 你是对的!好点,但他可以做一个简单的检查,比如颜色是否改变了,如果没有就刷新,然后什么都不做
    • 感谢您的建议。好的,我试过了,但还没有成功。我创建了一个公共静态最终字符串 PAGE_1_FRAGMENT = "page_1_fragment";在我的 Page_1.java 内部并在其中添加了 public void setUserVisibleHint(boolean isVisibleToUser) 。然后我添加了您的“如何刷新片段”代码并通过 PAGE_1_FRAGMENT 更改了“YourFragmentTag”。我还尝试了“page_1_fragment”,但没有成功。应用程序一启动就崩溃。
    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    相关资源
    最近更新 更多