如何在Fragment中更改ActionBar(Material Design)中的图像?

时间:2016-10-10 12:05:08

标签: android android-fragments material-design android-appbarlayout

查看带有图片的素材设计actionbar,请参阅Flexible space with image ImageView放置AppBarLayout。 如果在Android Studio中使用Activity创建Fragment,则会生成activity.xmlcontent_activity.xmlfragment.xml

activity.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context="com.example.app.MyActivity">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">

<android.support.design.widget.CollapsingToolbarLayout
    android:layout_width="match_parent"
    android:layout_height="172dp"
    app:contentScrim="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:titleEnabled="false">

    <ImageView
        android:id="@+id/bannerImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srcCompat="@drawable/banner_image"
        app:layout_collapseMode="parallax"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@null"
        app:layout_collapseMode="pin" />

</android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>

        <include layout="@layout/content_activity" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin" />

    </android.support.design.widget.CoordinatorLayout>

content_activity.xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragment"
    android:name="com.example.app.MyActivity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout="@layout/fragment"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

fragment.xml之:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...>
...
</RelaviteLayout>

我的问题是,如何在代码中动态更改ImageView AppbarLayout中的Fragment图片(请参阅上面的链接)? 更改操纵栏标题就像getActivity().setTitle("New_Title");一样简单,但如何引用和更改位于ImageView中的AppBarLayout中的图像只是在我之外。

我试过了:

在MyActivity.java中:

public class MyActivity extends AppCompatActivity {

    ImageView banner;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        banner = (ImageView) findViewById(R.id.bannerImageView);
    }

    void setBanner(int imgId) {

        if (banner != null) {
            banner.setImageResource(imgId);
        } else {
            Toast.makeText(this, "banner is null", Toast.LENGTH_LONG).show();
        }
    }
}
Fragment.java中的

int imgId = getActivity().getResources().getIdentifier(arrayItem.getBanner(),
                "drawable", getActivity().getPackageName());
    ((MyActivity) getActivity()).setBanner(imgId);

但引用为空。

2 个答案:

答案 0 :(得分:1)

imageView添加到AppBarLayout

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

            <ImageView
                android:id="@+id/imageView"
                android:scaleType="centerCrop"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize" />

    </android.support.design.widget.AppBarLayout>

您可以使用回调或在活动中声明一个方法,并通过调用getActivity()来使用它(警告:这不是正确的方法,因为片段应该用于多个活动)。

我认为你只使用单一活动,即MainActivity

在MainActivity.class

中声明此函数:setImage()
public void setImage(Drawable drawable){
    imageView.setImageDrawable(drawable);
}

另外,在onCreate()

中绑定对imageView的引用
imageView = findViewById(R.id.imageView);

现在,您可以在片段中调用((MainActivity)getActivity()).setImage(drawable)

<小时/> 参考问题 不应在片段的setImage()方法中调用上述onCreateView()调用。

因为在活动的setContentView()方法中调用onCreate()时实例化了片段视图。 android studio生成的存根代码静态地将片段添加到活动的布局中。

这是发生的调用序列 -

  • Activity : onCreateView()

  • Activity : setContentView()

  • Fragment : onCreate()

  • Fragment : onCreateView()

  • Instructions after setContentView()

  • Fragment : onActivityCreated()

在您的代码中,您已在setContentView()之后绑定了对横幅的引用,并且您可能在此绑定发生之前调用setBanner()

因此,要成功绑定引用并设置图像,请覆盖片段类中的onActivityCreated()并在那里调用setBanner()

答案 1 :(得分:0)

经过大量测试后,即使尝试在OnAttach的{​​{1}}中设置图片并尝试在Fragment中声明图片变量,我也意识到它与生命周期有关。

如果变量是在Activity中声明和设置的,那么它可以正常工作,但是如果在Activity中声明变量并尝试通过回调设置,则尝试完全相同的事情,然后失败,因为引用Fragment中的ImageView会返回null。尝试在AppBarLayout [ActionBar]中设置图标也可以复制此内容。

因此,我发现这对getActivity().getSupportActionBar().setIcon(Icon_Resource); activity fragment工作的唯一方法是在OnClick事件之类的事件启动后显示详细信息,是分割 bundle中的intent,在Activity级别使用部分内容,然后在Fragment级别使用其余部分。这样,可以在AppBar Activity's设置OnCreate视图,同时可以成功引用视图,其余视图可以在夸大的Fragment视图中设置。