【问题标题】:FragmentPagerAdapter to ViewPagerFragmentPagerAdapter 到 ViewPager
【发布时间】:2017-08-12 18:56:56
【问题描述】:

不久前我开始使用 Android Studio 并学习 Java,现在坚持将适配器应用于不同的 ViewPager。我自己没有足够的知识来解决此类组件的行为问题,并将感谢您的帮助。 (对不起我的英语

想法是:

1) 一列记录(如 Instagram 中的),可以上下滚动;

2) 每条记录都有一个可以左右滚动的图片块和一个文本块;

它的组织方式(另见屏幕截图):

1) (main.xml) 在主布局(ConstraintLayout) 上有nestedScrollView,我在其中包含了LinearLayout (records.xml)。这是记录列。

2) LinearLayout 在循环(record.xml)中填充记录。每条记录都是ConstraintLayout,包含ViewPager和TextView。

3) 在每条新添加的记录中,我尝试查找 ViewPager,我使用 setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager())) 将适配器设置为。

4) MyFragmentPagerAdapter 在 getItem 调用 RecordImageFragment.newInstance 时,创建新的 Fragment (RecordImageFragment.java)。

5)每个RecordImageFragment放置FrameLayout(record_images_pager.xml),在里面找到ImageView,把图片放在那里。

截图:

app running

project structure

问题是:

所有作品,但图片仅在第一张唱片中可见。 创建记录时,我还在那里找到 TextView (record.xml) 并为其设置文本。文本因记录而异(这很好),但只有第一个记录中的第一个 ViewPager 有图片。虽然适配器 (MyFragmentPagerAdapter) 在每个 ViewPager、OnPageChangeListener 调用中都有效,但跟踪位置:0-2。经过研究发现 RecordImageFragment 认为第一条记录是他的 ViewGroup.getRootView().getRootView() (不是适配器设置的记录)。直到现在我试图弄清楚,为什么片段(RecordImageFragment.java)的内容(record_images_pager.xml)没有添加到适配器设置的ViewPager,而是添加到第一个。

MainActivity.java

package example;

import android.os.*;
import android.support.v4.app.*;
import android.support.v4.view.*;
import android.support.v7.app.AppCompatActivity;
import android.util.*;
import android.view.*;
import android.widget.*;

public class MainActivity extends AppCompatActivity {
	@Override
    protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		addRecords();
	}
	
	public void addRecords()
	{
		for (int j = 1; j <= 10; j++  ) 
		{
			addNewRecord(j);
		}
	}
	public void addNewRecord(int id)
	{
		LinearLayout records = (LinearLayout) findViewById(R.id.records);
		// Add new record
		LayoutInflater inflater = getLayoutInflater();
		View record = inflater.inflate(R.layout.record, null, false);
		records.addView(record);
		// Set text to text field
		TextView title_tv = (TextView) record.findViewById(R.id.title);
		title_tv.setText("Запись " + id);
		//Find ViewPager, add adapter and page change listener
		ViewPager pager = (ViewPager) record.findViewById(R.id.pager);
		pager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager()));
		pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
		{
			@Override
			public void onPageSelected(int position) { Log.d("example", "Картинка сменилась на: " + position);}
			@Override
			public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
			@Override
			public void onPageScrollStateChanged(int state) {}
		});
	}
	
	private class MyFragmentPagerAdapter extends FragmentPagerAdapter
	{
		int[] internalPicts = {R.drawable.pict1, R.drawable.pict2, R.drawable.pict3};
		public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); }
		@Override
		public Fragment getItem(int pos) { return RecordImageFragment.newInstance(internalPicts[pos]); }
		@Override
		public int getCount() {
			return internalPicts.length;
		}
	}
}

RecordImageFragment.java

package example;

import android.os.Bundle;
import android.support.v4.content.*;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class RecordImageFragment extends android.support.v4.app.Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View layoutWithImage = inflater.inflate(R.layout.record_images_pager, container, false);
		//Find ImageView on layout and place drawable there
		ImageView image = (ImageView) layoutWithImage.findViewById(R.id.image);
		int imgId = getArguments().getInt("img");
		image.setImageDrawable(ContextCompat.getDrawable(getActivity(), imgId));
    	return layoutWithImage;
    }

    public static RecordImageFragment newInstance(int image) {
		RecordImageFragment f = new RecordImageFragment();
        Bundle b = new Bundle();
        b.putInt("img", image);
		f.setArguments(b);
        return f;
    }
}

【问题讨论】:

    标签: java android-fragments android-imageview layout-inflater fragmentpageradapter


    【解决方案1】:

    终于,经过数小时的搜索和尝试。我找到了答案。问题非常微妙。问题出在您的适配器上,您在适配器中使用FragmentManager 来管理片段。在随后的(第二行或第三行)中,我认为FragmentPagerAdapter 不会将getItem() 方法返回的项目视为新片段。所以你根本看不到它们。这可能是因为您使用相同的FragmentManager 来管理适配器。

    解决方案是通过使用基本的PagerAdapter 并自己实现instantiateItem()destroyItem() 来完全取消FragmentManager。这消除了对 Fragments 的需求,您可以简单地自己扩展 Image 视图。

    这是您需要替换 MyFragmentPagerAdapter 的新 MyPagerAdapter

    private class MyPagerAdapter extends PagerAdapter {
            int[] internalPicts = {R.drawable.dashboard, R.drawable.icon, R.drawable.mockup};
    
            public MyPagerAdapter() {
                super();
            }
    
            @Override
            public int getCount() {
                return internalPicts.length;
            }
    
            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }
    
            @Override
            public Object instantiateItem(ViewGroup collection, int position) {
    
                // Inflating layout
                LayoutInflater inflater = (LayoutInflater) collection.getContext()
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
                View view = inflater.inflate(R.layout.record_images_pager, null);
    
                ImageView image = (ImageView) view.findViewById(R.id.image);
    
                image.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), internalPicts[position]));
    
                collection.addView(view, 0);
                return view;
    
            }
    
            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView((View) object);
            }
        }
    

    最后确保替换 pager.setAdapter(new MyFragmentPagerAdapter()); pager.setAdapter(new MyPagerAdapter());

    你也不需要RecordImageFragment

    在 Android Studio 中测试。

    我阅读了this 以供参考。

    提示 - 将 ListView 与自定义适配器一起使用,而不是简单的 LinearLayout 来放置所有浏览器以实现平滑滚动。

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多