再Fragment中设置背景色,然后改变Activity的背景,通过应用内的广播LocalBroadcastManager

1、新建一个activity,命名为BroadTempActivity,如下:

public class BroadTempActivity extends AppCompatActivity {
    private LinearLayout ll_broad_temp;
    private BgChangeReceiver changeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broad_temp);

        ll_broad_temp = findViewById(R.id.ll_broad_temp);

        PagerTabStrip pts_tab = findViewById(R.id.pts_tab);
        pts_tab.setTextColor(Color.RED);
        pts_tab.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);

        ViewPager vp_content = findViewById(R.id.vp_content);
        ArrayList<GoodsInfo> goodsList = GoodsInfo.getDefaultList();
        BroadcastPagerAdapter adapter = new BroadcastPagerAdapter(getSupportFragmentManager(),goodsList);
        vp_content.setAdapter(adapter);
        vp_content.setCurrentItem(0);
    }

    @Override
    protected void onStart() {
        super.onStart();
        changeReceiver = new BgChangeReceiver();
        IntentFilter filter = new IntentFilter(BroadcastFragment.EVENT);
        LocalBroadcastManager.getInstance(this).registerReceiver(changeReceiver, filter);
    }

    @Override
    protected void onStop() {
        super.onStop();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(changeReceiver);
    }

    private class BgChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                int color = intent.getIntExtra("color", Color.WHITE);
                ll_broad_temp.setBackgroundColor(color);
            }
        }
    }
}

2、BroadTempActivity对应的布局文件为activity_broad_temp,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_broad_temp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.viewpager.widget.PagerTabStrip
            android:id="@+id/pts_tab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </androidx.viewpager.widget.ViewPager>
</LinearLayout>

3、ViewPager用到的适配器为BroadcastPagerAdapter,继承于FragmentStatePagerAdapter,如下:

public class BroadcastPagerAdapter extends FragmentStatePagerAdapter {
    private ArrayList<GoodsInfo> mGoodsList = new ArrayList<GoodsInfo>();

    public BroadcastPagerAdapter(@NonNull FragmentManager fm, ArrayList<GoodsInfo> mGoodsList) {
        super(fm);
        this.mGoodsList = mGoodsList;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return BroadcastFragment.newInstance(position, mGoodsList.get(position).pic, mGoodsList.get(position).desc);
    }

    @Override
    public int getCount() {
        return mGoodsList.size();
    }

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

4、BroadcastPagerAdapter中用到的Fragment为BroadcastFragment,如下:

public class BroadcastFragment extends Fragment {
    private static final String TAG = "BroadcastFragment";
    public static final String EVENT = "com.example.senior.fragment.BroadcastFragment";
    protected View mView;
    protected Context mContext;
    private int mPosition;
    private int mImageId;
    private String mDesc;
    private int mColorSeq = 0; // 背景颜色的序号
    private Spinner sp_bg;
    private boolean bFirst = true; // 是否是首次打开

    public static BroadcastFragment newInstance(int position, int image_id, String desc) {
        BroadcastFragment fragment = new BroadcastFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("position", position);
        bundle.putInt("image_id", image_id);
        bundle.putString("desc", desc);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mContext = getContext();
        if (getArguments() != null) {
            mPosition = getArguments().getInt("position");
            mImageId = getArguments().getInt("image_id");
            mDesc = getArguments().getString("desc");
        }
        mView = inflater.inflate(R.layout.fragment_broadcast, container, false);
        ImageView iv_pic = mView.findViewById(R.id.iv_pic);
        TextView tv_desc = mView.findViewById(R.id.tv_desc);
        iv_pic.setImageResource(mImageId);
        tv_desc.setText(mDesc);
        return mView;
    }

    @Override
    public void onStart() {
        super.onStart();
        initSpinner();
        receiver = new BgChangeReceiver();
        // 创建一个意图过滤器,只处理指定事件来源的广播
        IntentFilter filter = new IntentFilter(EVENT);
        // 注册广播接收器,注册之后才能正常接收广播
        LocalBroadcastManager.getInstance(mContext).registerReceiver(receiver, filter);
    }

    @Override
    public void onStop() {
        // 注销广播接收器,注销之后不再接收广播
        LocalBroadcastManager.getInstance(mContext).unregisterReceiver(receiver);
        super.onStop();
    }

    // 声明一个背景色变更的广播接收器
    private BgChangeReceiver receiver;

    // 定义一个广播接收器,用于处理背景色变更事件
    private class BgChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                mColorSeq = intent.getIntExtra("seq", 0);
                sp_bg.setSelection(mColorSeq);
            }
        }
    }

    private void initSpinner() {
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.item_select, mColorArr);
        sp_bg = mView.findViewById(R.id.sp_bg);
        sp_bg.setAdapter(adapter);
        sp_bg.setSelection(mColorSeq);
        sp_bg.setOnItemSelectedListener(new ColorSelectedListener());
    }

    private String[] mColorArr = {"白色", "黄色", "绿色", "青色", "蓝色"};
    private int[] mColorIdArr = {Color.WHITE, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE};

    class ColorSelectedListener implements AdapterView.OnItemSelectedListener {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if (!bFirst || mColorSeq != position) {
                mColorSeq = position;
                // 创建一个广播的意图
                Intent intent = new Intent(EVENT);
                intent.putExtra("seq", position);
                intent.putExtra("color", mColorIdArr[position]);
                // 通过本地的广播管理器来发送广播
                LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
            }
            bFirst = false;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    }
}

5、BroadcastFragment的布局文件为fragment_broadcast,如下:

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp">

        <TextView
            android:id="@+id/tv_bg"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="切换背景"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_bg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:spinnerMode="dialog"
            android:layout_toRightOf="@id/tv_bg" />
    </RelativeLayout>

    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="match_parent"
        android:layout_height="360dp"
        android:scaleType="fitCenter" />

    <TextView
        android:id="@+id/tv_desc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:textColor="@color/contentGray"
        android:layout_margin="10dp" />

</LinearLayout>

6、用到的模型为GoodsInfo,如下:

GoodsInfo模型

7、效果图如下:

  • 左边的图是默认进来的效果:
  • 右边的图是切换颜色之后的效果:

8、LocalBroadcastManager有关的方法主要是下面三个:

  • sendBroadcast :发送广播
  • registerReceiver :注册接收器,一般在onStart 或者onResume 方法中注册
  • unregisterReceiver :注销接收器,一般在onStop 或者onPause 方法中注册