一个或多个接口?

时间:2015-09-16 10:04:10

标签: android listview android-fragments android-listview fragment

我有一个Activity A,其中包含Fragment B,其中包含另一个Fragment C,其中包含ListView,其中包含一些列表项。

列表项如何与Activity进行通信?我必须逐级传递Activity参考级别,直到它到达列表项目为止?我必须创建多个接口,并将通信级别提升回Activity级别吗?

更新

在阅读 @Barend 的回答后,这是我的代码:Fragment C有一个界面CFragment B有一个B接口,扩展了CActivity A实现B,这意味着它还在C中实现方法。在Fragment C中,我有一个mListener字段,该字段已分配给getActivity()生命周期回调中的onAttach(Context)

2 个答案:

答案 0 :(得分:1)

如果您需要与const中的Activity进行通信,则只需使用fragment即可从任何嵌套Activity获取Fragment。 如果您需要getActivity() Fragment Activity FragmentManager FragmentManager manager = getFragmentManager(); Fragment f = manager.findFragmentByTag("Your fragment tag"); 使用class Crypter { /** * * Encryption key * * @var */ protected $key; /** * * Encryption vector * * @var */ protected $iv; public function __construct() { $this->key = config('auth.triple_des_key'); $this->iv = implode(array_map("chr", config('auth.triple_des_iv'))); } /** * * Decrypts string using tripleDES method. * * @param $input String * @return String */ public function decryptTripleDES($input) { $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, ''); $encryptedData = base64_decode($input); $key = iconv('utf-8', 'us-ascii//TRANSLIT', $this->key); $key = md5($key, true); $key .= substr($key, 0, 8); mcrypt_generic_init($td, $key, $this->iv); $decryptedData = mdecrypt_generic($td, $encryptedData); mcrypt_generic_deinit($td); //remove the padding text $block = mcrypt_get_block_size("tripledes", "cbc"); $packing = ord($decryptedData{strlen($decryptedData) - 1}); if ($packing and ($packing < $block)) { for ($P = strlen($decryptedData) - 1; $P >= strlen($decryptedData) - $packing; $P--) { if (ord($decryptedData[$P]) != $packing) { $packing = 0; } } } $decryptedData = substr($decryptedData, 0, strlen($decryptedData) - $packing); return $decryptedData; } } ,请访问clone

addAll

答案 1 :(得分:1)

如果你想要最干净的面向对象的结构,你可以使用多个接口,给回调接口提供与片段相同的嵌套结构,如下所示:

public class InnerFragment extends Fragment {

    public interface Callback {
        // Defines all callback methods required by inner fragment
    }
}

public class OuterFragment extends Fragment {

    public interface Callback
            extends InnerFragment.Callback {
        // Defines all callback methods required by outer fragment
        // Inherits all callback methods required by inner fragment
    }
}

public class HostActivity extends Activity
        implements OuterFragment.Callback {

    // implements the callback methods of both fragments, but
    // references only the outer fragment
}

您支付的价格是,这使您编写的代码比使用广播接收器或事件总线的代码多。

为什么这是最干净的方法?关注点分离和最少知识原则。活动仅与外部片段直接交互;内部片段是外部片段的实现细节。

要使内部片段起作用,活动必须实现内部回调。这是通过使外部回调扩展内部回调来实现的。

如果你勾勒出&#34;组件x了解组件y&#34;图表,你明白了:

Activity --> OuterFragment --> InnerFragment

这很干净。这些组件自包含独立,其依赖关系显式和(大部分)编译器检查。 InnerFragment是一个黑盒子&#34;外部片段的实现细节,它可以直接在不同的上下文中使用,如果回调没有改变(它们可能从一个片段的回调移动到另一个片段),任何一个片段都可以重构而不触及活动在某些情况下)。

如果您不使用callback-extends-callback技巧,那么您将获得此组件知识图:

Activity --> OuterFragment --> InnerFragment
         --------------------> InnerFragment

在这种情况下,内部片段回调依赖项对程序员是不可见的。如果您包含片段X,则您希望必须实现X.Callback,但是您还需要Y.Callback并不明显。由于这通常是通过Fragment onAttach()方法中的类型转换来实现的,因此在运行时获得ClassCastException之前,您不会发现。

顺便说一句,我不喜欢嵌套片段(DialogFragment很好,但我对嵌套常规片段持怀疑态度)。我认为片段增加了很多复杂性,我还没有真正遇到过这样的情况,即移动应用的小屏幕尺寸和单个任务焦点需要甚至是可以理解的。您通常最好使用自定义ViewGroup。我建议仅使用片段作为支持平板电脑上具有并排布局的手机上的堆叠布局的方式,甚至可以使用自定义ViewGroup以一种通常更简单但可以肯定的方式实现不太常见。