【问题标题】:TabLayout added same list itemTabLayout 添加了相同的列表项
【发布时间】:2018-03-26 20:32:51
【问题描述】:

我试图在 TabLayout 的片段中的列表视图中显示注册用户,但我的问题是,当我从一个选项卡布局滑动到另一个选项卡布局然后返回第一个选项卡布局时,它会复制相同的用户列表并重复添加到该列表中并且每当我滑动到其他选项卡布局时都会继续。我怎样才能解决这个问题? UserListFragment.java

public class UserlistFragment extends Fragment {
private static final String TAG = "UserList";
ListView usersList;
private DatabaseReference mDatabaseUser;
ArrayList<String> list=new ArrayList<>();
private DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot();

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.userlist_fragment,container,false);

    mDatabaseUser = FirebaseDatabase.getInstance().getReference("users");

    usersList = (ListView)view.findViewById(R.id.usersList);
    final ArrayAdapter<String> adapter=new ArrayAdapter<String>(getActivity(),android.R.layout.simple_dropdown_item_1line,list);
    usersList.setAdapter(adapter);
    usersList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            String s = usersList.getItemAtPosition(i).toString();
           /* Intent intent = new Intent(getApplicationContext(),Chat_Room.class);
            intent.putExtra("user_name",s);

            startActivity(intent);*/
        }
    });

    mDatabaseUser.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            /*list.add((String) dataSnapshot.getValue(String.class));*/

            User user = dataSnapshot.getValue(User.class);

            // Check for null
            if (user == null) {
                // Log.e(TAG, "User data is null!");
                return;
            }
            list.add(user.username);

            adapter.notifyDataSetChanged();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


    return view;
}

}

MainActivity.java

   public class MainActivity extends AppCompatActivity {

private static final String TAG ="MainActivity";
private SectionPageAdapter mSectionPageAdapter;
private ViewPager mViewPager;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mSectionPageAdapter = new SectionPageAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager)findViewById(R.id.container);

    setUpViewPager(mViewPager);

    TabLayout tabLayout = (TabLayout)findViewById(R.id.tab);
    tabLayout.setupWithViewPager(mViewPager);


    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

}

private void setUpViewPager(ViewPager viewPager){
    SectionPageAdapter adapter = new SectionPageAdapter(getSupportFragmentManager());
    adapter.addFragment(new UserlistFragment(), "Users");
    adapter.addFragment(new GroupFragment(), "Group");
    adapter.addFragment(new ProfileFragment(),"Profile");
    viewPager.setAdapter(adapter);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if (id == R.id.action_logout) {
        FirebaseAuth.getInstance().signOut();
        startActivity(new Intent(this, SignActivity.class));
        finish();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

}

Here is image

【问题讨论】:

  • 能否也包含 MainActivity 代码?您的代码中有 ViewPager 吗?
  • 有多少个选项卡,它们都是相同的片段...还是每个选项卡都包含不同类型的片段。我有一个可能的解决方案,但你的问题解释得不够充分,所以我可能会浪费我的时间。
  • 对此感到抱歉...是的,我当然包括在内。是的,它有 ViewPager,有 3 个标签,它们使用 3 个片段

标签: android listview android-fragments


【解决方案1】:

我还没有收到你的回复,所以我还是试着回答一下。

问题可能是您的 ChildEventListener 正在被创建并一次又一次地重新添加,而从未被删除。这可能是因为每次滑动到它时都会不必要地重新创建片段(因为在滑动时它没有保存在内存中)和/或因为 mDatabaseUser 对象以某种方式被 Firebase 视为静态并要求您即使包含该对象的片段已从内存中删除,也要删除侦听器。

有两种可能的解决方案。您可以使用其中一种,也可以同时使用两种:

1) 如果您使用的是 ViewPager,则添加以下代码:

int temp = // the number of tabs in your layout - 1
viewPager.setOffscreenPageLimit(temp);

这将确保片段在屏幕外时留在内存中,因此当您滑回它时,onCreateView() 方法将不会再次执行。

2) 对您的片段进行以下更改:

-- 改变你声明监听器的方式,以便你可以引用它:

ChildEventListener derp = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        /*list.add((String) dataSnapshot.getValue(String.class));*/

            User user = dataSnapshot.getValue(User.class);

            // Check for null
            if (user == null) {
                // Log.e(TAG, "User data is null!");
                return;
            }
            list.add(user.username);

            adapter.notifyDataSetChanged();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

mDatabaseUser.addChildEventListener(derp);

-- 添加如下方法:

@Override
public void onDetach() {
    super.onDetach();
    mDatabaseUser.removeEventListener(derp);
}

这将确保无论出于何种原因从内存中删除片段,侦听器都会被删除。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2017-05-26
    • 2016-08-20
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2021-07-13
    • 2013-05-10
    相关资源
    最近更新 更多