【问题标题】:Working with fragments inside viewpager - android在 viewpager 中使用片段 - android
【发布时间】:2015-03-01 23:25:03
【问题描述】:

我在查看器中的位置有问题。我有带有按钮的片段的容器布局。有些片段有图片,但有些没有。如果片段包含图像,我想显示按钮。我知道容器发送到片段的位置存在问题,但是如何处理容器中的位置,以及为什么在第一个片段 0 和 1 中存在容器发送到第一个片段的位置。

以下是我从代码中得到的示例: 例如,如果 16. 片段包含图像,则按钮显示在 15. 片段上,但我希望该按钮显示在同一片段(16.片段)中。

这是我的片段类代码

public class PitanjaFragment extends Fragment{

public static final String ARG_PAGE = "page";

private int broj;
private ImageView image;
public static String uri;
public static ListView listView;
public static boolean odgovoreno;

public static boolean tocno;
public static ArrayList<Odgovor> odgovorList;
private PitanjaAdapter adapter;
private DBTools db;

public static PitanjaFragment create(int pageNumber) {
    PitanjaFragment fragment = new PitanjaFragment();
    Bundle args = new Bundle();
    Log.i("broj u pageru je sljedeci", String.valueOf(pageNumber));
    args.putInt(ARG_PAGE, pageNumber);
    fragment.setArguments(args);
    return fragment;
}

public PitanjaFragment() {

}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    broj = getArguments().getInt(ARG_PAGE);
}

@Override
public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_pitanja, container, false);
    image = (ImageView) view.findViewById(R.id.imageSlikaImageView);
    db = new DBTools(getActivity());
    listView = (ListView) view.findViewById(R.id.listView);
    updateDisplay();
    return view;
}

public void updateDisplay() {
    image.setImageBitmap(null);
    for (int j = 0; j < ContainerIspiti.getAllImages.size(); j++) {
        if (ContainerIspiti.getAllImages.get(j).getIdPitanja() == ContainerIspiti.getAllPitanja.get(broj)
                .getIdPitanja()
                && ContainerIspiti.getAllImages.get(j).getNazivSlike() != null) {
            image.setVisibility(View.VISIBLE);
            ContainerIspiti.povecalo.setEnabled(true);
            uri = PregledZnakova.PHOTOS_BASE_URL
                    + ContainerIspiti.getAllImages.get(j).getNazivSlike();
            int rounded_value = 40;    
            DisplayImageOptions options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.placeholder).showStubImage(R.drawable.placeholder).cacheInMemory().cacheOnDisc().displayer(new RoundedBitmapDisplayer(rounded_value)).build();
            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity().getApplicationContext()).defaultDisplayImageOptions(options).build();               
            ImageLoader.getInstance().init(config); 
            ImageLoader.getInstance().displayImage(uri, image,options);

        } else {
            image.setVisibility(View.GONE);
            ContainerIspiti.povecalo.setEnabled(false);
        }
    }

    odgovorList = db.getAllOdgovore(Integer.toString(ContainerIspiti.getAllPitanja.get(broj)
            .getIdPitanja()));
    adapter = new PitanjaAdapter(getActivity(),
            R.layout.pitanja_entry, odgovorList);
    listView.setAdapter(adapter);

    for (int i=0;i<ContainerIspiti.getAllPitanja.size();i++){
        if (ContainerIspiti.getAllPitanja.get(i).isTocno()){
            Log.i("Ovo pitanje je tocno", ContainerIspiti.getAllPitanja.get(i).getTextPitanja());
        }
    }
}
}

这是容器类的代码

public class ContainerIspiti extends FragmentActivity{

private ImageView next, previous, odgovori, informacije;
public static ImageView povecalo;
private TextView textPitanja, brojPitanja;
private ViewPager pager;
private PagerAdapter mPagerAdapter;
public static ArrayList<Pitanja> getAllPitanja;
public static ArrayList<Pitanje_has_Slika> getAllImages;
private Intent intent;
private DBTools db = new DBTools(this);
private ProgressDialog pDialog;
private int broj = 0;
private Typeface custom_font;
private HashMap<Integer, List<Integer>> odgBrojPitanja;
private static RelativeLayout relative;
private List<Integer> kliknuti;
private static ImageView expandedImageView;
private static ImageLoaderConfiguration config;
private static DisplayImageOptions options;

@Override
protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    Bundle bundle = new Bundle();
    intent = getIntent();
    custom_font = Typeface.createFromAsset(getAssets(), "fonts/Aller.ttf");
    odgBrojPitanja = new HashMap<Integer, List<Integer>>();
    setContentView(R.layout.activity_container_pitanja);
    Dohvati d = new Dohvati();
    d.execute();
    relative = (RelativeLayout) findViewById(R.id.RelativeLayoutContainerPitanjeExpandedImageView);
    povecalo = (ImageView) findViewById(R.id.povecaloButtonPitanja);
    povecalo.setImageResource(R.drawable.gumb_povecalo);
    textPitanja = (TextView) findViewById(R.id.kategorijaTextViewPitanjeActivity);
    brojPitanja = (TextView) findViewById(R.id.brojPitanjaTextViewPitanjeActivity);
    pager = (ViewPager) findViewById(R.id.pagerPitanja);
    options = new DisplayImageOptions.Builder().cacheInMemory().cacheOnDisc().build();
    config = new ImageLoaderConfiguration.Builder(this.getApplicationContext()).defaultDisplayImageOptions(options).build();
}

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return PitanjaFragment.create(position);
    }

    @Override
    public int getCount() {
        return getAllPitanja.size();
    }

}

private class Dohvati extends AsyncTask<String, String, String>{

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(ContainerIspiti.this);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        getAllPitanja = db
                .getAllPitanja(intent.getStringExtra("id_kategorije"));
        getAllImages = db.getAllPitanjaImages();
        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        pDialog.dismiss();
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        pager.setAdapter(mPagerAdapter);
        pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
            @Override
            public void onPageSelected(int position) {

                invalidateOptionsMenu();
                broj = position;
                brojPitanja.setText(String.valueOf(broj+1) + "/" + String.valueOf(getAllPitanja.size()));
                for (int j = 0; j < getAllImages.size(); j++){
                    if (getAllPitanja.get(broj).getIdPitanja() == getAllImages.get(j).getIdPitanja()){
                        //Log.i("getAllImages koja sadrzi je sljedeca", getAllImages.get(j).getNazivSlike());
                        povecalo.setVisibility(View.VISIBLE);
                    } else {
                        povecalo.setVisibility(View.INVISIBLE);
                    }
                }
            }
        });
        textPitanja.setText(intent.getStringExtra("NAZIV_KATEGORIJE"));
        brojPitanja.setText(String.valueOf(broj+1) + "/" + getAllPitanja.size());
    }

}

public static void zoomImage(String uri){

    ImageLoader.getInstance().init(config); 
    ImageLoader.getInstance().displayImage(uri, expandedImageView,options);
    relative.bringToFront();
    relative.setVisibility(View.VISIBLE);
    expandedImageView.setScaleType(ScaleType.CENTER_INSIDE);
    expandedImageView.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {

            relative.setVisibility(View.GONE);

        }

    });

}

}

希望有人能帮忙。

【问题讨论】:

    标签: android android-fragments android-viewpager fragment android-fragmentactivity


    【解决方案1】:

    您在ContainerIspitiPitanjaFragment 中都运行了一个相同的for 循环,以确定是否显示图像,我认为问题可能在那里出现。相反,如果每个PitanjaFragment实例都标识了它是否有图片,你可以在ViewPager中查看选中的PitanjaFragment来判断是否显示按钮。

    我还没有测试过以下代码,但这应该足以为您指明正确的方向。

    首先,在PitanjaFragment 中添加一个私有布尔字段,以指示此实例是否正在显示图像:

    PitanjaFragment.java

    public class PitanjaFragment extends Fragment{
        private boolean isDisplayingImage;
    

    然后,在您确定是否显示图像后更新此字段:

    PitanjaFragment.java

        public void updateDisplay() {
            image.setImageBitmap(null);
            for (int j = 0; j < ContainerIspiti.getAllImages.size(); j++) {
                if (ContainerIspiti.getAllImages.get(j).getIdPitanja() == 
                        ContainerIspiti.getAllPitanja.get(broj).getIdPitanja()
                        && ContainerIspiti.getAllImages.get(j).getNazivSlike() != null) {
                    image.setVisibility(View.VISIBLE);
    
                    // the Views on an Activity instance should not be accessed statically
                    //ContainerIspiti.povecalo.setEnabled(true);
    
                    // Instead, update the new boolean field
                    isDisplayingImage = true;
    
                    // ...
    
                } else {
                    image.setVisibility(View.GONE);
    
                    // the Views on an Activity instance should not be accessed statically
                    //ContainerIspiti.povecalo.setEnabled(false);
    
                    // Instead, update the new boolean field
                    isDisplayingImage = false;
                }
            }
    
            // ...
        }
    

    然后,添加一个 getter 以便其他代码可以访问该值:

    PitanjaFragment.java

        public boolean hasImage() {
            return isDisplayingImage;
        }
    

    接下来,我们将转到ContainerIspiti.java,在这里我们将访问选定的PitanjaFragment 以查找它是否有图像,然后相应地设置povecalo 的状态。

    首先,将povecalo 更改回私有的非静态字段,因为我们不再尝试从PitanjaFragment 访问它(更多信息在此答案的末尾):

    ContainerIspiti.java

    public class ContainerIspiti extends FragmentActivity{
    
    private ImageView next, previous, odgovori, informacije, povecalo;
    //public static ImageView povecalo;
    

    然后,由于FragmentStatePagerAdapter 不提供按位置检索特定Fragment 的方法,您需要先将此功能添加到您的ScreenSlidePagerAdapter(有关此解决方案的更多信息,请参阅android - Retrieve a Fragment from a ViewPager):

    ContainerIspiti.java

        private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
            SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    
            // ...
    
            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                Fragment fragment = (Fragment) super.instantiateItem(container, position);
                registeredFragments.put(position, fragment);
                return fragment;
            }
    
            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                registeredFragments.remove(position);
                super.destroyItem(container, position, object);
            }
    
            public Fragment getRegisteredFragment(int position) {
                return registeredFragments.get(position);
            }
        }
    

    最后,你需要从选中的片段中获取hasImage()的值,并相应地设置povecalo的状态:

    ContainerIspiti.java

        private class Dohvati extends AsyncTask<String, String, String>{
            // ...
    
           pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
                @Override
                protected void onPostExecute(String result) {
                    // ...
    
                    pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
                        @Override
                        public void onPageSelected(int position) {
                            // ...
    
                            // Replace the for() loop with this
                            if (((PitanjaFragment) mPagerAdapter.getRegisteredFragment(position)).hasImage()) {
                                povecalo.setEnabled(true);
                                povecalo.setVisibility(View.VISIBLE);
                            }
                            else {
                                povecalo.setEnabled(false);
                                povecalo.setVisibility(View.INVISIBLE);
                            }
                        }
                    }
                });
    
                // ...
            }
        }
    

    同样,我没有测试过这段代码,所以如果你有任何问题,请发表评论。

    我想指出的另一件事是,使用静态字段来存储实例数据并不是一个好的解决方案,即使您确定只有一个对象实例。

    在这种情况下,我们清理了povecalo,但您仍在使用ActivityContainerIspiti 中的其他静态字段(getAllPitanjagetAllImages)来存储实例生成的数据的ContainerIspitiPitanjaFragment 然后直接从类中访问这些静态字段。

    相反,您至少应该考虑将它们设为私有的非静态字段,并使用 getter 方法从实例而不是类中访问它们。

    【讨论】:

    • 我在你的路上做。我更改了所有静态变量,但是这行代码 if ((PitanjaFragment) mPagerAdapter.getRegisteredFragment(position)).hasImage()) 有问题。他不希望我将 mPagerAdapter.getRegisteredFragment(position)).hasImage() 转换为 PitanjaFragment,我不知道为什么
    • 啊,对不起!我错过了一个左括号。我用更改更新了我的答案:if (((PitanjaFragment) mPagerAdapter.getRegisteredFragment(position)).hasImage()) {
    • 非常感谢。你救了我的命。还有一个问题。如果我想从 PitanjaFragment 中的 IspitiContainer 获取值 getAllPitanja,我需要使用 Boundle 还是可以使用 IspitiContainer 中的 getter 和 setter 来做到这一点
    • 您可以使用 getter/setter。例如,如果ContainerIspiti Activity 有方法public String getSomething(),您可以从PitanjaFragment((ContainerIsPiti) getActivity()).getSomething() 调用此方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多