Android Fragment——添加一个没有UI的Fragment
2015-08-28 12:32
302 查看
上节显示了怎样把Fragment作为UI的一部分添加到Activity上,但是,你也能够使用Fragment只提供一个后台行为,而没有额外的UI展现。
要添加一个没有UI的Fragment,需要在Activity中使用add(Fragment,String)(给Fragment提供一个唯一的字符串“tag”,而不是视图ID)方法来添加Fragment。但是,因为这样添加的Fragment没有跟Activity布局中的视图关联,它不接受对onCreateView()方法的调用,因此你不需要实现这个方法。
不能说提供了字符串“tag”的Fragment就是非UIFragment,因为你也可以给有UI的Fragment提供字符串“tag”,但是如果Fragment没有UI,那么只能使用字符串的方法来标识它。如果你想要从Activity获取这个Fragment,需要使用findFragmentByTag()方法。
FragmentRetainInstance.java演示了一个没有UI的使用Fragment作为后台工作器的Activity。
要添加一个没有UI的Fragment,需要在Activity中使用add(Fragment,String)(给Fragment提供一个唯一的字符串“tag”,而不是视图ID)方法来添加Fragment。但是,因为这样添加的Fragment没有跟Activity布局中的视图关联,它不接受对onCreateView()方法的调用,因此你不需要实现这个方法。
不能说提供了字符串“tag”的Fragment就是非UIFragment,因为你也可以给有UI的Fragment提供字符串“tag”,但是如果Fragment没有UI,那么只能使用字符串的方法来标识它。如果你想要从Activity获取这个Fragment,需要使用findFragmentByTag()方法。
FragmentRetainInstance.java演示了一个没有UI的使用Fragment作为后台工作器的Activity。
/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.apis.app; import com.example.android.apis.R; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; /** * This example shows how you can use a Fragment to easily propagate state (such * as threads) across activity instances when an activity needs to be restarted * due to, for example, a configuration change. This is a lot easier than using * the raw Activity.onRetainNonConfiguratinInstance() API. */ public class FragmentRetainInstance extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // First time init, create the UI. if (savedInstanceState == null) { getFragmentManager().beginTransaction().add(android.R.id.content, new UiFragment()).commit(); } } /** * This is a fragment showing UI that will be updated from work done in the * retained fragment. */ public static class UiFragment extends Fragment { RetainedFragment mWorkFragment; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_retain_instance, container, false); // Watch for button clicks. Button button = (Button) v.findViewById(R.id.restart); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { mWorkFragment.restart(); } }); return v; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); FragmentManager fm = getFragmentManager(); // Check to see if we have retained the worker fragment. mWorkFragment = (RetainedFragment) fm.findFragmentByTag("work"); // If not retained (or first time running), we need to create it. if (mWorkFragment == null) { mWorkFragment = new RetainedFragment(); // Tell it who it is working with. mWorkFragment.setTargetFragment(this, 0); fm.beginTransaction().add(mWorkFragment, "work").commit(); } } } /** * This is the Fragment implementation that will be retained across activity * instances. It represents some ongoing work, here a thread we have that * sits around incrementing a progress indicator. */ public static class RetainedFragment extends Fragment { ProgressBar mProgressBar; int mPosition; boolean mReady = false; boolean mQuiting = false; /** * This is the thread that will do our work. It sits in a loop running * the progress up until it has reached the top, then stops and waits. */ final Thread mThread = new Thread() { @Override public void run() { // We'll figure the real value out later. int max = 10000; // This thread runs almost forever. while (true) { // Update our shared state with the UI. synchronized (this) { // Our thread is stopped if the UI is not ready // or it has completed its work. while (!mReady || mPosition >= max) { if (mQuiting) { return; } try { wait(); } catch (InterruptedException e) { } } // Now update the progress. Note it is important that // we touch the progress bar with the lock held, so it // doesn't disappear on us. mPosition++; max = mProgressBar.getMax(); mProgressBar.setProgress(mPosition); } // Normally we would be doing some work, but put a kludge // here to pretend like we are. synchronized (this) { try { wait(50); } catch (InterruptedException e) { } } } } }; /** * Fragment initialization. We way we want to be retained and start our * thread. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Tell the framework to try to keep this fragment around // during a configuration change. setRetainInstance(true); // Start up the worker thread. mThread.start(); } /** * This is called when the Fragment's Activity is ready to go, after its * content view has been installed; it is called both after the initial * fragment creation and after the fragment is re-attached to a new * activity. */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Retrieve the progress bar from the target's view hierarchy. mProgressBar = (ProgressBar) getTargetFragment().getView().findViewById(R.id.progress_horizontal); // We are ready for our thread to go. synchronized (mThread) { mReady = true; mThread.notify(); } } /** * This is called when the fragment is going away. It is NOT called when * the fragment is being propagated between activity instances. */ @Override public void onDestroy() { // Make the thread go away. synchronized (mThread) { mReady = false; mQuiting = true; mThread.notify(); } super.onDestroy(); } /** * This is called right before the fragment is detached from its current * activity instance. */ @Override public void onDetach() { // This fragment is being detached from its activity. We need // to make sure its thread is not going to touch any activity // state after returning from this function. synchronized (mThread) { mProgressBar = null; mReady = false; mThread.notify(); } super.onDetach(); } /** * API for our UI to restart the progress thread. */ public void restart() { synchronized (mThread) { mPosition = 0; mThread.notify(); } } } }
相关文章推荐
- IOS UICollectionViewLayout详解
- 使用UIImageView播放图片
- 程序猿会不会找UI设计师做女朋友?
- [LeetCode] 187 - Repeated DNA Sequences
- soapui + groovy 接口自动化测试 第二章
- JS动态修改页面EasyUI datebox不生效、EasyUI动态添加Class、EasyUI动态渲染解析解决方案
- fineui经验积累1之EF实体关系对应对应错误
- soapui + groovy 接口自动化测试 第一章
- android 事件处理机制之requestDisallowInterceptTouchEvent详解
- Finui报错积累1之实体关系对应错误
- 【Material Design视觉设计语言】UI组件设计(六):分隔线
- Autofac QuickStart
- Java finished with non-zero exit value 2 - Android Gradle
- 使用continue语句
- android 布局xml中 android:fitsSystemWindows="true"
- 【Material Design视觉设计语言】UI组件设计(五):提示框
- UITableView设置cell为不可选?
- 解决方法]MySql提示:The server quit without updating PID file(…)失败
- 第1回——Web前端经典demo(新建用户弹窗,EasyUI+JQurey)
- UIAlertController的使用,代替UIAlertView和UIActionSheet