質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

1291閲覧

Android ViewPager でFragmentのImageViewを切り替える

kitarou

総合スコア8

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2019/09/12 06:55

解決できない問題があり、至急質問させて頂きたいです。
Android StudioでECサイト型のアプリ開発を行なっています。 
その商品詳細画面で、商品の写真を3枚、クリック又はスワイプで切り替える動作を行いたいです。
viewpagerでFragmentを3つ用意して、Fragment毎にimageviewを、photo1 photo2 photo3 を用意しています。
imageのpngデータはURLから取ってくる予定です。
urlから画像を取得してimageにsetしたいのですが、fragmentの3つ目だけ、参照先のfragmentのphoto3がないとエラーが出ます。
void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)' on a null object reference ....

以下ni
fragmewntを格納してadapterに繋いでいますが、この中で3つ目のfragmentだけがどうして null object になるのかわかりません。
val fragments = arrayListOf(Product_photo1Fragment(), Product_photo2Fragment(), Product_photo3Fragment())

お気付きのことなどありましたら、教えて頂けると幸いです。
よろしくお願いいたします。

以下にコードを記載いたします。

adapter はこちら

public class product_detail_adapter(fm: FragmentManager?, private var fragments: ArrayList<Fragment>) : FragmentPagerAdapter(fm) { lateinit var fragment : Fragment init { getItem(0) } override fun getCount(): Int { return fragments.size } override fun getItem(position: Int): Fragment { return fragments[position] }

表示するActivity のviewpagerの部分 image_1,image_2, image_3が画像のurlがstringで格納されている

//ここからviewpager処理 var current_page = 1 val pager = findViewById<ViewPager>(R.id.viewPager) val fragments = arrayListOf(Product_photo1Fragment(), Product_photo2Fragment(), Product_photo3Fragment()) val adapter = product_detail_adapter(supportFragmentManager, fragments) pager.adapter = adapter val url1 = URL("${image_1}") val tlstream1 = url1.openStream() val mbitmap1 =BitmapFactory.decodeStream(tlstream1) photo1.setImageBitmap(mbitmap1) val url2 = URL("${image_2}") val tlstream2 = url2.openStream() val mbitmap2 =BitmapFactory.decodeStream(tlstream2) photo2.setImageBitmap(mbitmap2) val url3 = URL("${image_3}") val tlstream3 = url3.openStream() val mbitmap3 =BitmapFactory.decodeStream(tlstream3) photo3.setImageBitmap(mbitmap3)

Fragmentの1つ 3つあるが内容はそれぞれ変数名以外は同じ

// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" private const val ARG_PARAM2 = "param2" /** * A simple [Fragment] subclass. * Activities that contain this fragment must implement the * [Product_photo3Fragment.OnFragmentInteractionListener] interface * to handle interaction events. * Use the [Product_photo3Fragment.newInstance] factory method to * create an instance of this fragment. * */ class Product_photo3Fragment : Fragment() { private var param1: String? = null private var param2: String? = null // private var listener: OnFragmentInteractionListener? = null // override fun onCreate(savedInstanceState: Bundle?) { // super.onCreate(savedInstanceState) // arguments?.let { // param1 = it.getString(ARG_PARAM1) // param2 = it.getString(ARG_PARAM2) // } // } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_product_photo3, container, false) } // fun onButtonPressed(uri: Uri) { // listener?.onFragmentInteraction(uri) //} // override fun onAttach(context: Context) { // super.onAttach(context) // if (context is OnFragmentInteractionListener) { // listener = context // } else { // throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener") // } //} //override fun onDetach() { // super.onDetach() // listener = null //} /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * * * See the Android Training lesson [Communicating with Other Fragments] * (http://developer.android.com/training/basics/fragments/communicating.html) * for more information. */ // interface OnFragmentInteractionListener { // fun onFragmentInteraction(uri: Uri) // } companion object { /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment Product_photo3Fragment. */ @JvmStatic fun newInstance(param1: String, param2: String) = Product_photo3Fragment().apply { arguments = Bundle().apply { putString(ARG_PARAM1, param1) putString(ARG_PARAM2, param2) } } } }

fragmentのXML こちらもそれぞれ変数名以外は同じ

<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical" tools:context=".Product_photo3Fragment"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/photo3" android:scaleType="centerCrop" app:srcCompat="@drawable/pic_product_07"/> </LinearLayout>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ViewPagerが保持するView(Fragment)のキャッシュは、デフォルトでは「今表示しているView+左右のViewの計3つ」です。ですので最初のページを表示した段階では、右隣の2ページ目までしか読み込まれず3ページ目のViewはまだ生成されていません。

ですので、各ページのViewに関する処理は、各Fragment内で行うようにするのがベストです。Activity(Adapter)側からは画像のURLだけを渡して、Fragment側で表示される際に読み込んでImageViewに表示されるようにします。

  • Activity側

kotlin

1val fragments = arrayListOf( 2 Product_photo1Fragment().apply { arguments = bundleOf("url" to image_1) }, 3 Product_photo2Fragment().apply { arguments = bundleOf("url" to image_2) }, 4 Product_photo3Fragment().apply { arguments = bundleOf("url" to image_3) } 5)
  • Fragment側

kotlin

1override fun onActivityCreated(savedInstanceState: Bundle?) { 2 super.onActivityCreated(savedInstanceState) 3 4 val url = requireArguments().getString("url") 5 // urlから画像を読み込み... 6}

投稿2019/09/13 05:41

編集2019/09/13 05:42
kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kitarou

2019/09/14 06:07

教えて頂いた通りの実装で期待の挙動が実現できました。 各ページのViewの処理はそれぞれで行わないといけないということがわかってよかったです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問