可重用的视图?

Posted

技术标签:

【中文标题】可重用的视图?【英文标题】:Reusable views? 【发布时间】:2017-11-11 13:03:47 【问题描述】:

我是 android 开发新手,但我有相当多的 Swing/WPF(C#) GUI 经验。我正在尝试做的是以下内容:

我有一个BottomNavigationView,有 3 个单独的视图。每个视图都实现为一个片段,通过OnNavigationItemSelectedListener 在 MainActivity java 代码中显示/隐藏:

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() 

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) 
        switch (item.getItemId()) 
            case R.id.one:
                findViewById(R.id.one).setVisibility(View.VISIBLE);
                findViewById(R.id.two).setVisibility(View.GONE);
                findViewById(R.id.threee).setVisibility(View.GONE);
                return true;
    // ... and so on

我的问题是两个片段的一部分接口是相同的,由一组EditTextImageButton组成。所以我想创造一些可重用的东西,而不是加倍代码。我的选择是在片段中制作片段(但在互联网上我看到这是不可取的)或制作可重复使用的视图(https://developer.android.com/training/improving-layouts/reusing-layouts.html,https://developer.android.com/guide/topics/ui/custom-components.html)。最好的方法是什么?我想要一个带有连接的 java 代码的 xml 布局,我可以在其中收听与 EditTextButtons 的交互并采取相应的行动。也许我对我的 WPF 经验有偏见,但我试图让它像一个 xaml + 代码隐藏,这可能不是在构建 Android 应用程序时解决问题的正确方法。

【问题讨论】:

如果您希望在 Java 代码中的相同视图中执行相同的方法,请声明静态方法以根据您的应用程序逻辑执行相同的操作,但我已经给出了如何重用视图的答案,但是如果这不是您想在我的问题中发表评论并解释我将编辑我的答案的内容! 【参考方案1】:

您将不得不为您将多次使用的视图定义单独的 XML 布局,并且

在 XML 中 您将在布局中使用 <include> 标签,例如

 ...
<include layout="@layout/your_frequent_used_layout"/>

<TextView android:layout_
          android:layout_
          android:text="@string/hello"
          android:padding="10dp" />
....

更多信息here in the documentation training!

在 Java 中 对于 Java 方面,如果您想获得某个视图并添加到当前布局,您将需要一个布局 Inflater,然后在您的活动中像这样添加到您的 View如果它抛出任何错误,请在您的片段中考虑上下文)

第一个选项:

View view = null;
LayoutInflater inflater = 
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.your_reusable_view, null);
your_main_root_view.addView(view);

第二个选项:

View child = getLayoutInflater().inflate(R.layout.your_reusable_view, null);
your_main_root_view.addView(child);

【讨论】:

好的,谢谢。是否有可能有一堂课让我可以收听这些 EditText 和 Buttons 引发的事件?还是应该在 MainView 中实现监听器? 是的,用接口和方法创建一个类,并在你的 mainView 类中实现接口。 把整个想法告诉我,这样我就能明白了!并回答它! 我很高兴你解决了你的问题@Marco 快乐编码!【参考方案2】:

根据您在问题中的代码,您只是显示/隐藏布局中存在的视图。 因此,首先我建议将 BottomNavigationViewViewPager 结合使用,并为每个导航项创建独立的片段。 本文演示了如何开始http://droidmentor.com/bottomnavigationview-with-viewpager-android/

其次,对于所有包含公共项的片段,您将创建一个抽象的 BaseFragment 来管理所有公共逻辑。 扩展此抽象片段以创建您的个人片段并膨胀独特的布局。

fragment_base.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_>

    <!--- Your Common Elements Here --->

    <!--- Unique Elements will get inserted here --->

</LinearLayout>

fragment_nav_unique1.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_
    android:layout_>

    <!--- Unique Elements For the Nav View Item --->

</LinearLayout>

BaseFragment.java

public abstract class BaseFragment extends Fragment 

    // Get Layout resource id of the Individual Fragments
    protected abstract int layoutResourceId();

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        // Inflate the base layout
        LinearLayout view = (LinearLayout) inflater.inflate(R.layout.fragment_base, container, false);

        // Inflate the unique layouts and add them to the view    
        LinearLayout uniqueView = (LinearLayout) inflater.inflate(layoutResourceId(), null);
        view.addView(uniqueView);

        // Return view
        return view;
    

    //--- Manage all the Common Elements here ---


FirstFragment.java

public class FirstFragment extends BaseFragment 
    @Override
    protected int layoutResourceId() 
        // Return the resource of the unique layout
        return R.layout.fragment_nav_unique1;
    

    //--- Manage all the Unique Elements here ---


【讨论】:

【参考方案3】:

使用 CustomView 是解决这个问题的方法。您不仅可以在其中使用相同的布局文件,还可以在自定义视图实现中定义与此视图的类似交互。

【讨论】:

以上是关于可重用的视图?的主要内容,如果未能解决你的问题,请参考以下文章

可重用的视图?

可重用的 TableView 标题视图

Swift 可重用视图

表视图出列可重用单元格重叠

如何创建和使用可重用的视图模板

Spring MVC可重用视图组件[重复]