【发布时间】:2017-04-13 14:30:01
【问题描述】:
我对 Android 有点陌生,特别是 Fragments,我遇到了这个我无法解决的问题,我在这里搜索过,发现了一些类似的问题,但没有一个能帮助解决我的问题:
我有一个包含 TabLayout 和 ViewPager 以及片段适配器的活动。 PageAdapter 从数据库中获取一些数据并将其发送到三个片段。用户可以更改活动中的日期,并且应该重新加载新数据。
活动第一次加载后,在 API 16/17 上一切正常,但从 18 开始,它不会显示任何数据。此外,当用户更改日期时,第一个和最后一个选项卡会正确更新数据,但第二个和中间选项卡会一直显示过去的内容。
CardapioActivity 的代码
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Locale;
public class CardapioActivity extends AppCompatActivity {
public TextView msg, data;
private DatePickerDialog toDatePickerDialog;
private SimpleDateFormat dateFormatter;
private Calendar myCalendar;
private TabLayout tabLayout;
private ViewPager viewPager;
private String restaurante;
private ArrayList<String> lista = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cardapio);
msg = (TextView) findViewById(R.id.tv1);
data = (TextView) findViewById(R.id.data);
Intent intent = getIntent();
restaurante = intent.getStringExtra("restaurante");
lista = intent.getStringArrayListExtra("lista");
msg.setText(restaurante);
msg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alertaRestaurante();
carregaFragment();
}
});
//formata data e possibilita seleção a partir do calendário
myCalendar = Calendar.getInstance();
dateFormatter = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
data.setText(dateFormatter.format(myCalendar.getTime()).toString());
data.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertaCalendario();
carregaFragment();
}
});
//fecha página caso clicado em close
final ImageButton close = (ImageButton) findViewById(R.id.close);
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//volta pra activity do mapa
Intent intent = new Intent(CardapioActivity.this, MainActivity.class);
CardapioActivity.this.startActivity(intent);
CardapioActivity.this.finish();
}
});
carregaFragment();
}
方法 carregaFrament() 负责创建 TabLayot 并使用 ViewPager 设置它
private void carregaFragment(){
//viewPager
viewPager = (ViewPager) findViewById(R.id.vp);
viewPager.setAdapter(new CustomSlidePageAdapter(getSupportFragmentManager(), CardapioActivity.this));
//tabLayout
tabLayout = (TabLayout) findViewById(R.id.tab);
tabLayout.setupWithViewPager(viewPager);
}
这是 PagerAdapter
private class CustomSlidePageAdapter extends FragmentStatePagerAdapter {
Bundle bundle = new Bundle();
private String pages [] = {"DESJEJUM", "ALMOÇO", "JANTA"};
private Context context;
public CustomSlidePageAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
ArrayList<Cardapio> lista_desjejum = carregaCardapio("desjejum", msg.getText().toString(), data.getText().toString());
bundle.putParcelableArrayList("lista_desjejum", lista_desjejum);
// set Fragmentclass Arguments
DesjejumFragment desjejum = new DesjejumFragment();
desjejum.setArguments(bundle);
return desjejum;
case 1:
ArrayList<Cardapio> lista_almoco = carregaCardapio("almoco", msg.getText().toString(), data.getText().toString());
bundle.putParcelableArrayList("lista_almoco", lista_almoco);
// set Fragmentclass Arguments
AlmocoFragment almoco = new AlmocoFragment();
almoco.setArguments(bundle);
return almoco;
case 2:
ArrayList<Cardapio> lista_janta = carregaCardapio("janta", msg.getText().toString(), data.getText().toString());
bundle.putParcelableArrayList("lista_janta", lista_janta);
// set Fragmentclass Arguments
JantaFragment janta = new JantaFragment();
janta.setArguments(bundle);
return janta;
default:
return null;
}
}
@Override
public int getCount() {
return pages.length;
}
@Override
public CharSequence getPageTitle(int position){
return pages[position];
}
}
这里是三个 Fragment 的一个例子,它们的编码都是相似的
import android.support.v4.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
public class DesjejumFragment extends ListFragment {
private ArrayList<Cardapio> c = new ArrayList<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
c = getArguments().getParcelableArrayList("lista_desjejum");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_desjejum, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ListaCardAdapter adapter = new ListaCardAdapter(getActivity(), c);
setListAdapter(adapter);
}
}
这里有一些图片来说明问题:
first time on the left, changed date on the right
in the middle tag it doesn't change
当我尝试在 API 级别 >18 上切换选项卡时,这里有一些 logcat
04-12 23:13:16.831 31009-31009/br.ufrrj.lothar.rural D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
04-12 23:13:16.941 31009-7797/br.ufrrj.lothar.rural I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
04-12 23:13:16.941 31009-7797/br.ufrrj.lothar.rural I/qtaguid: Tagging socket 48 with tag ad7277400000000{181872500,0} for uid -1, pid: 31009, getuid(): 10169
04-12 23:13:16.981 31009-7797/br.ufrrj.lothar.rural I/qtaguid: Untagging socket 48
04-12 23:13:17.551 31009-31009/br.ufrrj.lothar.rural D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
04-12 23:13:19.661 31009-31009/br.ufrrj.lothar.rural D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
04-12 23:13:19.791 31009-7859/br.ufrrj.lothar.rural I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
04-12 23:13:19.791 31009-7859/br.ufrrj.lothar.rural I/qtaguid: Tagging socket 48 with tag ad7277400000000{181872500,0} for uid -1, pid: 31009, getuid(): 10169
04-12 23:13:19.841 31009-7859/br.ufrrj.lothar.rural I/qtaguid: Untagging socket 48
04-12 23:13:20.741 31009-31009/br.ufrrj.lothar.rural D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
04-12 23:13:22.611 31009-31009/br.ufrrj.lothar.rural D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
04-12 23:13:22.741 31009-7910/br.ufrrj.lothar.rural I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
04-12 23:13:22.741 31009-7910/br.ufrrj.lothar.rural I/qtaguid: Tagging socket 48 with tag ad7277400000000{181872500,0} for uid -1, pid: 31009, getuid(): 10169
04-12 23:13:22.781 31009-7910/br.ufrrj.lothar.rural I/qtaguid: Untagging socket 48
有人可以帮我吗? P.S.:对于葡萄牙语中的一些变量和方法,提前抱歉,可能会造成混淆。
更新:在 API 级别 21 上,它仅在中间选项卡中显示内容,23 它不显示任何内容。
【问题讨论】:
-
我建议不要使用参数这样做,因为这些只能在片段初始化时发送。如您所见,使用 ViewPager 时,创建片段时无法预测,因此您不应该依赖它。此外,您应该只关心更新当前查看的页面上的数据。看看这个答案,它显示了如何动态更新 ViewPager 中显示的当前 Fragment 的数据:stackoverflow.com/a/36504458/4409409
-
我希望我能投票给你的答案(我不能投票给 cmets 可以吗?)我听从了你的建议,并在创建片段之前开始加载数据,现在它适用于所有版本的 android。不过,我仍然遇到错误,每当我更新它时,中间片段都不会显示内容,知道它可能是什么吗? @DanielNugent P.s.:onpagechange 事情没有奏效:/
标签: android android-fragments android-viewpager