我有一个布局中带有碎片容器的Activity
。
可以在其中显示3个不同的Fragment
。
这些碎片包含一个使用我自己制作的自定义适配器显示数据的Listview
。
因此,在每个列表元素创建期间,我都会在onCreateView
中查询数据库以获取数据。
但有时我的数据库中可能会更改一些数据,因此我想重新绘制/重建Listview
。
- 最好的方法是什么(我是指,资源需求最少)来刷新我的碎片视图?
- 是否有一种方法可以手动调用
onCreateView
?
我有一个布局中带有碎片容器的Activity
。
可以在其中显示3个不同的Fragment
。
这些碎片包含一个使用我自己制作的自定义适配器显示数据的Listview
。
因此,在每个列表元素创建期间,我都会在onCreateView
中查询数据库以获取数据。
但有时我的数据库中可能会更改一些数据,因此我想重新绘制/重建Listview
。
onCreateView
?分离并附加它
Fragment currentFragment = getFragmentManager().findFragmentByTag("YourFragmentTag");
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.detach(currentFragment);
fragmentTransaction.attach(currentFragment);
fragmentTransaction.commit();
或者使用搜索片段
Fragment currentFragment = getActivity().getSupportFragmentManager().findFragmentById(R.id.container);
Handler
处理,它使我能够处理“静态”考虑。谢谢。 - Heretyk将两个答案合并并删除 if (isVisibleToUser)
,因为它会以不可预测的异步顺序调用 setUserVisibleHint
,从而导致片段可能被刷新或不被刷新。我发现在您的 Fragment 中,这段代码是稳定的:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
// Refresh tab data:
if (getFragmentManager() != null) {
getFragmentManager()
.beginTransaction()
.detach(this)
.attach(this)
.commit();
}
}
有一种非常有用的Fragment
方法,可以用于刷新片段。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//Write down your refresh code here, it will call every time user come to this fragment.
//If you are using listview with custom adapter, just call notifyDataSetChanged().
}
}
FragmentManager fm = getSupportFragmentManager();
//if you added fragment via layout xml
Fragment fragment = fm.findFragmentById(R.id.your_fragment_id);
if(fragment instanceof YourFragmentClass) // avoid crash if cast fail
{
((YourFragmentClass)fragment).showPrayer();
}
Fragment fragment = fm.findFragmentByTag("yourTag");
if(fragment instanceof YourFragmentClass)
{
((YourFragmentClass)fragment).showPrayer();
}
((NavigationHost) getActivity()).navigateTo(new MyNotesFragment(), false);
import androidx.fragment.app.Fragment;
public interface NavigationHost {
void navigateTo(Fragment fragment, boolean addToBackstack);
}
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity implements NavigationHost {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new LoginFragment())
.commit();
}
}
@Override
public void navigateTo(Fragment fragment, boolean addToBackstack) {
FragmentTransaction transaction =
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment);
if (addToBackstack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
}
#我的项目使用Android Navigation构建了片段#
MainList片段调用FilterDialog片段。 在程序和用户完成Filter对话框的工作后,按下返回按钮返回到MainList片段并根据请求刷新它。如果您有Viewmodel并且能够共享数据,则很容易实现。
我先给你结论,然后是导致它的编码链。
*val navController = findNavController()
navController.run{ popBackStack()
navigate(mViewModel. FilterDialogReturnTarget )}`*
这将弹出后退栈并正确刷新返回的片段,以反映对过滤器的更改。
>>> Viewmodel:
import androidx.lifecycle.ViewModel …….
class MainActivityViewModel : ViewModel() { ……
var FilterDialogReturnTarget:Int=0…….
>>navigation Graph
navigation/nglist.xml
<navigation …….
<fragment
android:id="@+id/nav_main_list" ……
>>>MainList.kt
class MainList : androidx.fragment.app.Fragment(){……
import App.name.name.viewmodel.MainActivityViewModel
private val mViewModel: MainActivityViewModel by activityViewModels()
private fun setUpListeners() {….
binding.vemlBtnFilterOn.setOnClickListener {…….
mViewModel.FilterDialogReturnTarget = R.id.nav_main_list
findNavController().navigate(R.id.action_main_list_to_FilterDialog)
}
>>>FilterDialog.kt
import androidx.fragment.app.DialogFragment
import app.name.name.MainActivityViewModel
class ElectionsFilterDialog : DialogFragment(){…..
private val mViewModel: MainActivityViewModel by activityViewModels()
private fun setUpListeners() {….
binding.vemlBtnFilterOn.setOnClickListener {…….
val navController = findNavController()
navController.run{ popBackStack()
navigate(mViewModel.FilterDialogReturnTarget )}
这对我来说非常完美,因为我已经有了视图模型和导航。
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
class EventBus {
private val _events = MutableSharedFlow<AppEvent>()
val events = _events.asSharedFlow()
suspend fun emitEvent(event: AppEvent) {
_events.emit(event)
}
}
AppEvent
是一个枚举类型,例如:enum class AppEvent {
TODO_LIST_UPDATED
}
AppEvent
,而不是枚举。eventBus.emitEvent(AppEvent.TODO_LIST_UPDATED)
init {
viewModelScope.launch {
eventBus.events
.filter { it == AppEvent.TODO_LIST_UPDATED }
.collectLatest {
val todosResponse = todoRepository.getTodos()
_todos.value = todosResponse.todos
}
}
}
你的片段将观察 LiveData 并在检索到新数据后在适配器上设置数据。
如果你没有视图模型,你可以直接在片段中使用 lifecycleScope
来实现,但是现在推荐使用视图模型并实现 MVVM 架构。
确保你的事件总线实例是单例实例,以便所有消费者都发布和订阅同一个总线。你可以使用依赖注入框架来实现这一点,并按照该框架创建单例的指示进行操作。
你可以在我写的 关于此主题的博客文章 中详细了解事件总线模式。
这个方法对我有效:
MyCameraFragment f2 = new MyCameraFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, f2);
transaction.addToBackStack(null);
transaction.commit();
以下代码在适配器中刷新一个片段
DownloadsAdapter 代码:
public class DownloadsAdapter extends RecyclerView.Adapter<DownloadsAdapter.ViewHolder> {
private Context mCtx;
//getting the context and product list with constructor
public DownloadsAdapter(Context mCtx, List<DataModel> fileUrlLinkList) {
this.mCtx = mCtx;
this.fileUrlList = fileUrlLinkList;
}
**... and in onBindViewHolder**
FragmentManager manager = ((AppCompatActivity) mCtx).getSupportFragmentManager();
Fragment currentFragment = manager.findFragmentByTag("DOWNLOADS");
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.detach(currentFragment);
fragmentTransaction.attach(currentFragment);
fragmentTransaction.commit();
...
}
设置你想要刷新的片段
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if(isVisibleToUser){
if (getFragmentManager() != null) {
getFragmentManager()
?.beginTransaction()
?.detach(this)
?.attach(this)
?.commit();
}
}
}