用另一个列表替换主活动中的列表并从视图中删除旧列表

Posted

技术标签:

【中文标题】用另一个列表替换主活动中的列表并从视图中删除旧列表【英文标题】:Replace list in master activity with another list and remove old list from view 【发布时间】:2015-08-06 05:16:36 【问题描述】:

当盯着我的应用程序时,主片段中会显示一个列表 (list_main)。当我从主列表片段中单击第一个列表项时,还有一个应该打开的第二个列表片段,但是在单击第一个列表项后,主列表片段确实消失了,但第二个列表没有出现,因此主片段保持空白。此外,当我单击后退按钮时,主列表不会重新出现。有谁知道为什么会出现这些问题以及如何解决这些问题?

主要活动 XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:orientation="horizontal"
    android:showDividers="middle"
    tools:context=".MainActivity" >

    <fragment
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:id="@+id/master_container"
        android:name="com.apptacularapps.exitsexpertlondonlite.FragmentMainList"/>

    <FrameLayout
        android:layout_
        android:layout_
        android:layout_weight="3"
        android:id="@+id/detail_container"/>

</LinearLayout>

主列表片段 XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_
    android:id="@+id/fragmentmainlist">

    <ListView
        android:id="@+id/list_main"
        android:layout_
        android:layout_
        android:layout_centerVertical="false"
        android:layout_centerHorizontal="true"/>
</LinearLayout>

主列表片段类

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public class FragmentMainList extends android.support.v4.app.Fragment 

    ListView list_main;

    String[] listContent = 
            "Item 1",
            "Item 2",
            "Item 3"
    ;


    private boolean mTwoPane;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        View v = inflater.inflate(R.layout.fragment_main_list, container, false);
        list_main = (ListView)v.findViewById(R.id.list_main);

        list_main = (ListView)findViewById(R.id.list_main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listContent);
        list_main.setAdapter(adapter);

        list_main.setOnItemClickListener(new AdapterView.OnItemClickListener() 

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) 

                if (mTwoPane) 
                    for (int j = 0; j < adapterView.getChildCount(); j++)
                        adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

                    // change the background color of the selected list view item
                    view.setBackgroundColor(Color.parseColor("#00BCD4"));
                


                if (position == 0) 
                    if (mTwoPane) 
                        FragmentItem1 newFragment = new FragmentItem1();
                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

                        list_main.setVisibility(View.GONE);
                        transaction.replace(R.id.master_container, newFragment);
                        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                        transaction.addToBackStack(null);

                        transaction.commit();
                     else 

                    
                

                if (position == 1) 

                

                if (position == 2) 

                
            
        );

        return v;
    

主要活动类

public class MainActivity extends ActionBarActivity 

    ListView list_main;

    String[] listContent = 
            "Station Chooser",
            "Item 2",
            "Item 3"
    ;

    private boolean mTwoPane;

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

        list_main = (ListView)findViewById(R.id.list_main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listContent);
        list_main.setAdapter(adapter);

        list_main.setOnItemClickListener(new AdapterView.OnItemClickListener() 

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) 
                    if (position == 0) 
                    if (mTwoPane) 
                        FragmentStationChooser newFragment = new FragmentStationChooser();
                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();


                        transaction.replace(R.id.master_container, newFragment);
                        transaction.addToBackStack(null);

                        transaction.commit();

                    getSupportFragmentManager().executePendingTransactions();
                     else 

                    
                

                if (position == 1) 
                

                if (position == 2) 
                
            
        );

        if (findViewById(R.id.detail_container) != null) 
            mTwoPane = true;
        
    

选台片段

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_>

    <ListView
        android:id="@+id/list_linechooser"
        android:layout_
        android:layout_
        android:layout_centerVertical="false"
        android:layout_centerHorizontal="true"/>
</LinearLayout>

站点选择器片段类

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentStationChooser extends android.support.v4.app.Fragment 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        return inflater.inflate(R.layout.fragment_station_chooser, container, false);
    


Station Chooser Activity 类

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class StationChooserActivity extends ActionBarActivity 

    ListView list_linechooser;

    String[] listContent = 
            "Line 1",
            "Line 2",
            "Line 3"
    ;

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

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(false);

        list_linechooser = (ListView)findViewById(R.id.list_linechooser);
        list_linechooser.setAdapter(adapter);

        list_linechooser.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) 
            
        );
    

@Override
    public void onBackPressed() 
        if (mTwoPane) 
            FragmentMainList newFragment = new FragmentMainList();
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            list_main.setVisibility(View.VISIBLE);
            transaction.replace(R.id.master_container, newFragment).commit();

            transaction.addToBackStack(null);
        
    

【问题讨论】:

你有什么具体问题。什么不工作? 2nd list to replace 1st list - which method? 的可能重复项 你确定mTwoPanetrue 吗?贴出FragmentStationChooser的代码。 @MacaronLover 你确定mTwoPane 确实是true 是的,但你确定是true 吗?否则交易永远不会被执行,难怪你什么都看不到。 【参考方案1】:

在弹出后台堆栈时片段未显示的主要问题是您试图在另一个片段 id 中膨胀该片段,这是代码的这一部分:

transaction.replace(R.id.master_container, newFragment);

您不需要一个全新的活动来托管您在FragmentStationChooser 中所做的另一个片段。

现在你需要做的是有一个容器来在你的活动主中托管你的片段,而不是让片段标签用一个容器代替它,比如相对布局:

替换这个:

<fragment android:layout_ android:layout_ android:layout_weight="1" android:id="@+id/master_container" android:name="com.apptacularapps.exitsexpertlondonlite.FragmentMainList"/>

<RelativeLayout android:layout_ android:layout_ android:layout_weight="1" android:id="@+id/master_container"/>

完成此操作后,在您的主要活动中删除所有列表视图代码并将其转移到您的FragmentMainList您在膨胀时使用视图的位置:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) View v = inflater.inflate(R.layout.fragment_main_list, container, false); list_main = (ListView)v.findViewById(R.id.list_main); .//the logic from your activity main transfered here in the FragmentMainList . . return v;

最后在您的FragmentStationChooser 中执行相同操作,不要使用活动StationChooserActivity,只需将其从您的项目中删除即可

编辑:

删除list_main.setVisibility(View.GONE);,因为它在膨胀时会被片段替换

编辑 2:

在您的主要活动的 onCreate 中添加:

@Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FragmentMainList newFragment = new FragmentMainList();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.master_container, newFragment);    
        transaction.commit();

【讨论】:

移动我的代码后,我遇到了 3 个错误。查看最新截图。 @MacaronLover 第一个错误应该是v.findViewById 如上面的示例,第二个错误将this 更改为getActivity(),第三个错误更改为FragmentMainList.this.getActivity().getSupportFragmentManager() 我现在收到一条警告说“FragmentMainList”类从未使用过。 酷。现在,应用程序确实运行且没有崩溃,但在选择列表项后,新列表不会在主片段中打开,而是在新窗口中打开(参见最新的 2 个屏幕截图)。 @MacaronLover 也许您正在开始一个新活动,请尝试使用上面的代码,例如单击列表项中的 oncreate,但不要将 FragmentMainList 更改为 FragmentStationChooser【参考方案2】:

由于您过去的 cmets 和我将代码从 StationChooserActivity.java 移动到 FragmentStationChooser

的建议

FragmentStationChooser 类的代码:

    String[] listContent = 
            "Line 1",
            "Line 2",
            "Line 3"
    ;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        View v =  inflater.inflate(R.layout.fragment_station_chooser, container, false);
        ListView list_linechooser = (ListView) v.findViewById(R.id.list_linechooser);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.fragment_station_chooser, listContent);
        list_linechooser.setAdapter(adapter);

        return v;
    

这是一个开始。我尽力了解您的帖子和问题。祝你好运。

【讨论】:

NB:list_main 是我想从视图中消失的那个。不知道为什么在我的应用程序首次启动时该列表已经存在时使用View.VISIBLElist_main 是我的应用程序启动时首先出现的列表。我希望将其替换为list_linechooser,以便list_linechooser 出现在用户的设备上+ 当按下后退按钮时,我希望list_linechooser 从视图中消失并重新出现list_main @MacaronLover,您是否意识到 list_linechooser ListView 是在另一个 Activity 而不是 Fragment 上声明的,这是一种常见的方式?但我很困惑,fragment_station_chooser 布局 xml 文件在另一个文件 FragmentStationChooser.java 中被引用。也许将 StationChooserActivity.java 中的代码放到 FragmentStationChooser. 是的,我意识到这一点,但我也为 list_main 列表视图做到了这一点。我将它放在另一个活动中,因为我希望这些列表项在单击时执行其他操作。 list_linechooser 代码是否需要放入我的 FragmentStationChooser.java 文件中?我可以向您发送我的项目的 zip 文件吗? @MacaronLover,是的,list_linechooser 代码应该移动到 FragmentStationChooser.java。您有一个误解,即 Fragment 子类不能执行 GUI 代码或单击事件,事实并非如此。在您的情况下,将所有 UI 操作放在 Fragment 中。如果我有时间,我可能会根据我对您的设计的理解用一些代码更新我的帖子。 @MacaronLover,关于您的代码,我希望您将它们发布到 Github 网站上,以便其他人查看或更新您原始帖子中的代码。您可以继续在帖子中添加新代码与旧代码。【参考方案3】:

看来StationChooserActivity 是您的主要活动,没有其他活动。你没有提到。

您的应用唯一要做的就是根据数组 listContent 将“第 1 行”、“第 2 行”和第 3 行显示到列表视图中。这是由于代码MyColoringAdapter adapter = new MyColoringAdapter(this,listContent)

另外,当用户点击 Back 键时,如果 mTwoPane 为 true,则可能会显示一个新的 Fragment FragmentMainList,但不确定。之后我认为您的应用将退出。

注意:主要活动并没有做太多事情。我不认为那是意图。您需要确定如何处理它。这是我最好的建议。

【讨论】:

我的主要活动代码在主要活动类下的顶部。 Main Activity 的目标是显示一个列表(它已经这样做了),当单击“项目 1”时,该列表应该消失(它确实如此)并且另一个列表应该出现(这不会发生)。这是我遇到的主要问题,它没有出现,我不知道为什么也不知道如何解决这个问题。 你知道我的另一个错误有什么问题吗? Error question

以上是关于用另一个列表替换主活动中的列表并从视图中删除旧列表的主要内容,如果未能解决你的问题,请参考以下文章

用另一个视图替换选项卡

在片段中使用列表视图

根据字符串名称而不是列表视图项位置替换片段并启动活动

将保存在数据库 sqlite 中的列表视图中的一行发送到另一个列表视图,并使其与第一个列表视图中的行相同

如何从列表视图中的项目单击中获取歌曲在android中

更新和删除列表视图中的行