如何在填充了 BaseAdapter 的 Fragment 中刷新 ListView?
Posted
技术标签:
【中文标题】如何在填充了 BaseAdapter 的 Fragment 中刷新 ListView?【英文标题】:How to Refresh ListView in Fragment that is filled with BaseAdapter? 【发布时间】:2013-06-04 03:31:32 【问题描述】:我想在关闭对话框时刷新片段中的 ListView。到目前为止,刷新仅在我重新启动应用程序时才有效,我真的不知道为什么。
以下是课程:
这是一个带有 ListView 的片段,我想在对话框关闭时刷新它。
public class RegisterListFragment extends Fragment
public static final String TAG = "RegisterListFragment";
RegisterListAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
setRetainInstance(true);
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.act_select_list_fragment, container, false);
ListView list = (ListView) view.findViewById(R.id.register_list);
list.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3)
Intent i = new Intent(getActivity(), com.example.smartkasse.Act_Register.MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
TextView selectedRegisterTextView = (TextView) arg1.findViewById(R.id.title);
String selectedRegisterName = (String) selectedRegisterTextView.getText();
i.putExtra("selectedRegisterName", selectedRegisterName);
startActivity(i);
getActivity().finish();
);
adapter = new RegisterListAdapter(getActivity());
list.setAdapter(adapter);
return view;
public void refreshData()
adapter.notifyDataSetChanged();
这是我填写列表的适配器:
public class RegisterListAdapter extends BaseAdapter
View view = null;
Database db = new Database(mContext);
data=db.getAlltitles();
if(convertView==null)
view = (View) inflater.inflate(R.layout.act__select_listview, null);
TextView title = (TextView) view.findViewById(R.id.title);
TextView artist = (TextView) view.findViewById(R.id.artist);
TextView duration = (TextView) view.findViewById(R.id.duration);
ImageView thumb_image = (ImageView) view.findViewById(R.id.list_image);
title.setText(data.get(position));
//artist.setText(data.get(position));
//duration.setText(data.get(position));
//thumb_image.setImageResource(R.drawable.ic_launcher);
return view;
else
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView artist = (TextView) convertView.findViewById(R.id.artist);
TextView duration = (TextView) convertView.findViewById(R.id.duration);
ImageView thumb_image = (ImageView) convertView.findViewById(R.id.list_image);
title.setText(data.get(position));
// artist.setText(data.get(position));
// duration.setText(data.get(position));
//thumb_image.setImageResource(R.drawable.ic_launcher);
return convertView;
这是将所有东西结合在一起的主要:
当按下对话框的 positv 按钮时,新数据将添加到我想要的数据库中
public class MainActivity extends SherlockFragmentActivity implements OnRegisterCreatedListener
RegisterListFragment registerListFragment;
HelpFragment helpFragment;
boolean helpVisible = false;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// Grund-Layout für die Activity festlegen
setContentView(R.layout.act_select_main);
addFragments();
supportInvalidateOptionsMenu();
setLargeInLandscape();
// Was passiert wenn der Menüknopf gedrückt wird
// Inflate the menu; this adds items to the action bar if it is present.
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Zeigt nur die die nicht in Actionbar sind, kann aber eingestellt
// werden im XML-File
if (helpVisible)
getSupportMenuInflater().inflate(
R.menu.act_select_menu_help_visible, menu);
else
getSupportMenuInflater().inflate(
R.menu.act_select_menu_registerlist_visible, menu);
return true;
// Was passiert wenn ein Menüpunkt ausgewählt wird
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle item selection
switch (item.getItemId())
// Das wenn der Knopf das Plus war
case R.id.menu_help:
changeFragment();
// this.supportInvalidateOptionsMenu();
break;
case android.R.id.home:
changeFragment();
// this.supportInvalidateOptionsMenu();
break;
case R.id.menu_add_register:
FragmentManager fm = getSupportFragmentManager();
NewRegisterFragment dialog = new NewRegisterFragment();
dialog.setRetainInstance(true);
dialog.show(fm, "fragment_name");
break;
// Listenelement hinzufügen und dem Adapter sagen es hat sich was
// geändert, mach neu
return true;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
// TODO Auto-generated method stub
switch (keyCode)
case KeyEvent.KEYCODE_BACK:
if (helpVisible = true)
// changeFragment();
helpVisible = false;
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
supportInvalidateOptionsMenu();
break;
return super.onKeyDown(keyCode, event);
private void addFragments()
// Zuerst versuchen Fragmente aus dem Layout zu laden
registerListFragment = (RegisterListFragment) getSupportFragmentManager()
.findFragmentById(R.id.registerListFragment);
helpFragment = (HelpFragment) getSupportFragmentManager()
.findFragmentById(R.id.HelpFragment);
// Wenn die Fragmente nicht im Layout sind, füge sie dynamisch hinzu
if (registerListFragment == null && helpFragment == null)
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
registerListFragment = new RegisterListFragment();
helpFragment = new HelpFragment();
ft.setCustomAnimations(android.R.anim.fade_in,
android.R.anim.fade_out, android.R.anim.fade_in,
android.R.anim.fade_out);
ft.add(R.id.Fragmentframe, registerListFragment);
ft.add(R.id.Fragmentframe, helpFragment);
ft.show(registerListFragment);
ft.hide(helpFragment);
ft.commit();
// OnclickListener für Fragmentwechseln
private void changeFragment()
// Fragmente austauschen
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (registerListFragment.isVisible())
ft.hide(registerListFragment);
ft.show(helpFragment);
helpVisible = true;
supportInvalidateOptionsMenu();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (getSupportFragmentManager().findFragmentByTag(
"RegisterListFragment") == null)
ft.addToBackStack("RegisterListFragment");
else
ft.hide(helpFragment);
helpVisible = false;
supportInvalidateOptionsMenu();
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
fm.popBackStack();
ft.commit();
private void setLargeInLandscape()
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
findViewById(R.id.menu_help).setVisibility(View.GONE);
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
findViewById(R.id.menu_help).setVisibility(View.GONE);
@Override
public void OnRegisterCreated()
// TODO Auto-generated method stub
registerListFragment.refreshData();
在listView“后面”看到对话框。我尝试了很多,但我真的没有得到它。希望你能帮助我。
谢谢:)
【问题讨论】:
在 UI 线程中加载数据不是一个好主意。看看 CursorLoader (developer.android.com/reference/android/content/…) 或自定义 AsyncTaskLoader。为了简单地解决您的问题,您需要创建适配器的新实例并将其设置为 ListView 【参考方案1】:你可以这样做
public void refresh()
adapter = new RegisterListAdapter(getActivity());
list.setAdapter(adapter);
刷新 listView 或使用不同的适配器将数据保存在内存中。
编辑:对不起,我第一次没看清楚你的问题,你可以在你的适配器里写这个:
public void addNewRow(String row)
this.data.add(row);
this.notifyDataSetChanged();
【讨论】:
是的,这对我有用。但我认为这不是这样做的“最佳做法”。你知道如何更好地解决这个问题吗?因为这样我也可以调用 getActivity.findViewbyId(R.id.list) 然后添加一个新的适配器。我认为这不是你这样做的方式。【参考方案2】:试试ListView.invalidateViews()刷新内容
【讨论】:
我试过 list.invalidateViews 而不是 adapter.notifyDataSetChanged();但它也没有用-.-' 请确保您的数据在调用前已更改。 Database.getAlltitles() - 返回的结果是否随时改变? 奇怪的是,当添加第一个项目并且我关闭 Activity 并重新启动它时,它就可以工作了。我真的很困惑。 我认为 invalidateView 不会停止,因为数据在适配器构造函数中加载了一次。尝试创建新的适配器实例并将其设置为查看 谢谢!这对我有用。你们需要一起使用 adapter.notifyDataSetChanged();在它之后 list.invalidateViews() NOT INSTEAD OF!【参考方案3】:我使用Interface
方法。创建一个Interface
类
interface RefreshListview
fun onValueChanged(myList: ArrayList<ModelTask>)
在您的 Activity
类中实现 Interface
及其方法
class MenuAct : AppCompatActivity(), View.OnClickListener,RefreshListview
在方法内部获取更改后的列表并设置为您的CustomAdapter
override fun onValueChanged(myList: ArrayList<ModelTask>)
notesAdapter = AdapterTask(this, myList) // handle your own Adapter and listview `static` initilisations
lv_act_menu_daily.adapter = notesAdapter
哦,现在我们在 DialogFragment
类中
private var mCallback: RefreshListview? = null
这很重要
override fun onAttach(activity: Activity?)
super.onAttach(activity)
try
mCallback = activity as RefreshListview?
catch (e: ClassCastException)
Log.d("MyDialog", "Activity doesn't implement the RefreshListview interface")
内部onActivityCreated
try
// handle your actions
dBHelper.deleteTaskByID(myProg.id!!)
//get the current listview
var daily = dBHelper.readAllTask(Util.getInstance(context).currentTime)
//send it to Interface method
mCallback?.onValueChanged(daily)
dismiss()
catch (e:Exception)
e.printStackTrace()
【讨论】:
以上是关于如何在填充了 BaseAdapter 的 Fragment 中刷新 ListView?的主要内容,如果未能解决你的问题,请参考以下文章
Android - 带有自定义 BaseAdapter 的 Gridview,在位置获得点击视图
Android - 带有自定义 BaseAdapter 的 Gridview,创建 onclicklistener [重复]