当我所做的只是跟随代码时,片段如何将自身附加到活动上。
public class FragmentA extends Fragment{
@Override
public View onCreateView(Layout inflater,ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_b, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState){
Button test = (Button) getActivity().findViewById(R.id.fragBtn1);
}
}
我对上面的代码感到困惑,因为我不太确定当我声明的是上面的代码并将片段添加到main_activity.XMl布局文件中时,片段是如何绑定到活动的。
所以我唯一的假设是XML布局引用了主要活动,因为它是由活动中的setContentView()调用的。作为此引用的结果,XMl文件能够将活动的上下文传递给片段,直到片段,从而允许片段绑定到活动上。
我在这个假设中是否正确?
答案 0 :(得分:2)
如果您在布局XML中添加了<fragment>
标记,则表明应该实例化具有指定类名的片段,并将其添加到Activity的视图层次结构中,同时保留其余部分视图层次结构正在实例化。这就产生了所谓的“硬连线”片段,它消除了片段所要提供的大量功能和灵活性。一个严重的限制是该片段无法删除或替换为同一活动UI中的另一个片段。
另一种方法是自己实例化片段,通常在宿主活动的onCreate()
方法中,并使用FragmentManager
将片段添加到活动中。这是使用一个名为FragmentTransaction的东西完成的。
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.frame_layout_container, new FragmentA());
transaction.commit();
此处R.id.frame_layout_container
指的是您的UI中的小部件,通常是FrameLayout
,您已经专门添加了该小部件以包含该片段。这类似于将任何其他小部件添加到RelativeLayout
或LinearLayout
。 FrameLayouts专门用于阻止部分UI关闭以保存一个组件,如片段。
为了清晰起见,我将此代码扩展了一些。 FragmentTransaction
是一个流体构建器接口,这意味着大多数transaciton方法返回更新的FragmentTransaction
,以便您可以将它们链接在一起。看到这样的事情更常见:
getFragmentManager().beginTransaction().add(R.id.frame_layout_container,
new FragmentA()).commit();
以这种方式使用片段管理器会创建一个“动态片段”,它可以替代硬连线片段。这些类型的碎片更加灵活。例如,它们可以交换进出UI,也可以保留它们(这意味着当主机活动由于配置更改(如旋转屏幕)而创建和销毁时保留)。大多数开发人员认为这是更好的方法,即使最初的硬接线片段看起来更容易。
在任何一种情况下,片段都有一个特殊的生命周期方法,当它附加到主机活动时被调用。这种名为onAttach(Activity a)
的方法是您以某种方式与主机活动进行交互的机会。
在任何情况下,片段都不会“绑定”自己的活动。相反,它是隐式创建的(在硬连线片段的情况下)或显式(通过片段管理器)附加到主机活动。
答案 1 :(得分:1)
-160
- &gt;你刚回答了自己的问题:)
有关详细信息,请粘贴 override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
timerAudio = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "checkTime", userInfo: nil, repeats: true)
self.audioPlayer?.meteringEnabled
playAudio( false, SongNumber: 2)
}
func checkTime() {
self.audioPlayer?.updateMeters()
self.audioPlayer?.numberOfChannels
let normalizedValue = self.audioPlayer?.averagePowerForChannel(0)
print(normalizedValue)
self.waveformView.updateWithLevel(CGFloat(normalizedValue!))
}
func playAudio( stopAudio:Bool, SongNumber: Int) {
let songNumber = SongsArray
let songNumberMediaPlayer = SongsArray
nameSong(songNumber[SongNumber])
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
//print("AVAudioSession Category Playback OK")
do {
try AVAudioSession.sharedInstance().setActive(true)
//print("AVAudioSession is Active")
} catch let error as NSError {
print(error.localizedDescription)
}
} catch let error as NSError {
print(error.localizedDescription)
}
let dispatchQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(dispatchQueue, {
let mainBundle = NSBundle.mainBundle()
/* Find the location of our file to feed to the audio player */
let filePath = mainBundle.pathForResource(songNumber[SongNumber], ofType:"mp3")
if let path = filePath{
let fileData = NSData(contentsOfFile: path)
do {
/* Start the audio player */
self.audioPlayer = try AVAudioPlayer(data: fileData!)
guard let player = self.audioPlayer else{
return
}
/* Set the delegate and start playing */
player.delegate = self
if player.prepareToPlay() && player.play(){
/* Successfully started playing */
} else {
/* Failed to play */
}
} catch{
self.audioPlayer = nil
return
}
if stopAudio == true {
self.audioPlayer?.pause()
self.timerAudio.invalidate()
}else {
self.audioPlayer?.play()
}
}
})
}
,我假设您拥有硬编码(仅限容器)片段参考。所以,是的,Android将找到该类(或者如果找不到类-fragment-则抛出异常)。
根据经验,我通常认为这是坏练习(直接在XML中硬编码片段),因为它有一些限制(特别是当涉及到嵌套碎片)它使得更难找到“这个片段来自何处”。 ;)
我忘了提到:硬编码片段的另一个缺点是你不能替换它们。因此,如果您尝试将Fragment替换为另一个片段,如果前者是XML格式的Harcoded,则不能,因为added the fragment into the main_activity.XMl layout file.
需要 Container (如FrameLayout或类似)放置片段,而不是之前的片段。
来源:http://developer.android.com/training/basics/fragments/creating.html
提取:
注意:通过在布局XML文件中定义片段将片段添加到活动布局时,无法在运行时删除片段。如果您计划在用户交互期间将片段交换进出,则必须在活动首次启动时将片段添加到活动中
更新了澄清说明:
片段将自身绑定到布局资源文件让我感到困惑
确定。片段不会将其自身绑定到任何东西。您告诉Android(通过XML)活动“Main”具有main_activity.xml
中指定的布局。当活动需要设置其内容时,它会解析此XML并发现有FragmentManager#replace(id)
的引用,其main_activity.xml
属于Fragment
类型。这会自动解决(如果找到这样的类)。
然后片段(并且您粘贴了此代码)正在其class
方法(您提供的方法)中加载其内容。然后,一旦活动可以,这个硬连线片段就会生效。
FragmentA
?这通常在JavaDocs中用于分隔Type和Method / Function。示例:onCreateView
或#
等