【问题标题】:Send Data from a fragment to another fragment将数据从一个片段发送到另一个片段
【发布时间】:2015-12-02 12:31:03
【问题描述】:

我需要从Second_frag 启动List_activity,但出现错误。 这是我的代码

public class Second_frag extends android.support.v4.app.Fragment {

String RSSFEEDURL = "http://feeds.feedburner.com/TwitterRssFeedXML?format=xml";
RSSFeed feed;
String fileName;

View myView;

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


    fileName = "TDRSSFeed.td";

    File feedFile = getActivity().getBaseContext().getFileStreamPath(fileName);

    ConnectivityManager conMgr = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    if (conMgr.getActiveNetworkInfo() == null) {

        // No connectivity. Check if feed File exists
        if (!feedFile.exists()) {

            // No connectivity & Feed file doesn't exist: Show alert to exit
            // & check for connectivity
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setMessage(
                    "Unable to reach server, \nPlease check your connectivity.")
                    .setTitle("TD RSS Reader")
                    .setCancelable(false)
                    .setPositiveButton("Exit",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog,
                                                    int id) {
                                    getActivity().finish();
                                }
                            });

            AlertDialog alert = builder.create();
            alert.show();
        } else {

            // No connectivty and file exists: Read feed from the File
            Toast.makeText(Second_frag.this.getActivity(), "No connectivity. Reading last update", Toast.LENGTH_LONG).show();
            feed = ReadFeed(fileName);
            startLisActivity(feed);
        }

    } else {

        // Connected - Start parsing
        new AsyncLoadXMLFeed().execute();

    }
    return myView;


}

private void startLisActivity(RSSFeed feed) {

    Bundle bundle = new Bundle();
    bundle.putSerializable("feed", feed);

    // launch List activity
    Intent intent = new Intent(getActivity(), List_Activity.class);

    intent.putExtras(bundle);
    startActivity(intent);

    // kill this activity
    getActivity().finish();

}

private class AsyncLoadXMLFeed extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {

        // Obtain feed
        DOMParser myParser = new DOMParser();
        feed = myParser.parseXml(RSSFEEDURL);
        if (feed != null && feed.getItemCount() > 0)
            WriteFeed(feed);
        return null;

    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);

        startLisActivity(feed);
    }

}

// Method to write the feed to the File
private void WriteFeed(RSSFeed data) {

    FileOutputStream fOut = null;
    ObjectOutputStream osw = null;

    try {
        fOut = getActivity().openFileOutput(fileName, Context.MODE_PRIVATE);
        osw = new ObjectOutputStream(fOut);
        osw.writeObject(data);
        osw.flush();
    }

    catch (Exception e) {
        e.printStackTrace();
    }

    finally {
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// Method to read the feed from the File
private RSSFeed ReadFeed(String fName) {

    FileInputStream fIn = null;
    ObjectInputStream isr = null;

    RSSFeed _feed = null;
    File feedFile = getActivity().getBaseContext().getFileStreamPath(fileName);
    if (!feedFile.exists())
        return null;

    try {
        fIn = getActivity().openFileInput(fName);
        isr = new ObjectInputStream(fIn);

        _feed = (RSSFeed) isr.readObject();
    }

    catch (Exception e) {
        e.printStackTrace();
    }

    finally {
        try {
            fIn.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return _feed;

}



}

列表活动

 public class List_Activity extends Fragment {

Application myApp;
RSSFeed feed;
ListView lv;
CustomListAdapter adapter;

View myView;

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


    myApp = getActivity().getApplication();

// Get feed form the file
    feed = (RSSFeed) getActivity().getIntent().getExtras().get("feed");

// Initialize the variables:
    lv = (ListView) getView().findViewById(R.id.listView);
    lv.setVerticalFadingEdgeEnabled(true);

// Set an Adapter to the ListView
    adapter = new CustomListAdapter(this);
    lv.setAdapter(adapter);

// Set on item click listener to the ListView
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView arg0, View arg1, int arg2,
                                long arg3) {
// actions to be performed when a list item clicked
            int pos = arg2;

            Bundle bundle = new Bundle();
            bundle.putSerializable("feed", feed);
            Intent intent = new Intent(getActivity(),
                    DetailActivity.class);
            intent.putExtras(bundle);
            intent.putExtra("pos", pos);
            startActivity(intent);

        }
    });
    return myView;
}

@Override
public void onDestroy() {
    super.onDestroy();
    adapter.imageLoader.clearCache();
    adapter.notifyDataSetChanged();
}

class CustomListAdapter extends BaseAdapter {

    private LayoutInflater layoutInflater;
    public ImageLoader imageLoader;

    public CustomListAdapter(List_Activity activity) {

        layoutInflater = (LayoutInflater) activity
                .getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getActivity());
    }

    @Override
    public int getCount() {

// Set the total list item count
        return feed.getItemCount();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

 // Inflate the item layout and set the views
        View listItem = convertView;
        int pos = position;
        if (listItem == null) {
            listItem = layoutInflater.inflate(R.layout.list_item, null);
        }

  // Initialize the views in the layout
        ImageView iv = (ImageView) listItem.findViewById(R.id.thumb);
        TextView tvTitle = (TextView) listItem.findViewById(R.id.title);
        TextView tvDate = (TextView) listItem.findViewById(R.id.date);

 // Set the views in the layout
        imageLoader.DisplayImage(feed.getItem(pos).getImage(), iv);
        tvTitle.setText(feed.getItem(pos).getTitle());
        tvDate.setText(feed.getItem(pos).getDate());

        return listItem;
    }
}
}

日志猫

 09-07 10:38:30.836  24588-24588/com.example.samsung.drawer E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.samsung.drawer, PID: 24588
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.samsung.drawer/com.example.samsung.drawer.List_Activity}: java.lang.ClassCastException: com.example.samsung.drawer.List_Activity cannot be cast to android.app.Activity
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225)
            at     android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:149)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(Native Method)
         Caused by: java.lang.ClassCastException: com.example.samsung.drawer.List_Activity cannot be cast to android.app.Activity
            at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2216)
            at         android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at     android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:149)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(Native Method)

RSSFeed.Java

import java.io.Serializable;
import java.util.List;
import java.util.Vector;

public class RSSFeed implements Serializable {

    private static final long serialVersionUID = 1L;
    private int _itemcount = 0;
    private List<RSSItem> _itemlist;

    RSSFeed() {
        _itemlist = new Vector<RSSItem>(0);
    }

    void addItem(RSSItem item) {
        _itemlist.add(item);
        _itemcount++;
    }

    public RSSItem getItem(int location) {
        return _itemlist.get(location);
    }

    public int getItemCount() {
        return _itemcount;
    }

}

RSSItem.Java

package com.example.samsung.drawer;

import java.io.Serializable;

public class RSSItem implements Serializable {

    private static final long serialVersionUID = 1L;
    private String _title = null;
    private String _description = null;
    private String _date = null;
    private String _image = null;

    void setTitle(String title) {
        _title = title;
    }

    void setDescription(String description) {
        _description = description;
    }

    void setDate(String pubdate) {
        _date = pubdate;
    }

    void setImage(String image) {
        _image = image;
    }

    public String getTitle() {
        return _title;
    }

    public String getDescription() {
        return _description;
    }

    public String getDate() {
        return _date;
    }

    public String getImage() {
        return _image;
    }

}

谁能告诉我如何解决这个问题?

【问题讨论】:

  • 你正在尝试将 Fragment 投射到 Activity.. 你不能这样做。
  • 也使用viewholder模式

标签: android android-fragments


【解决方案1】:

List_Activity 是 Fragment 而不是 Activity,您不能以 startActivity 启动它

如果要替换当前的Fragment,使用FragmentManager

【讨论】:

    【解决方案2】:

    List_Activity 是一个片段。你不能使用

    Intent intent = new Intent(getActivity(), List_Activity.class);
    
    intent.putExtras(bundle);
    startActivity(intent);
    

    您可以使用接口作为对托管活动的回调。然后将数据从activity传递给List_Activity Fragment。

    此外,您可能希望将上下文传递给适配器 custructor

    http://developer.android.com/training/basics/fragments/communicating.html

    【讨论】:

    • 但是 OP 也可以使用set setArguments(bundle) 方法传递数据,并且 OP 还需要使用 FragmentManager 将 Fragment 添加到 Activity,而不是作为 Activity 启动
    • @ρяσѕρєяK 是的,他可以。但是它的 Fragment to Fragment 通信,我建议它可以通过托管活动来完成。
    • 我忘了说片段需要附加到活动中。
    【解决方案3】:

    如果这两个Fragment附加在一个Activity中,则可以通过Activity在两个Fragment之间进行通信。在每个片段中,您使用 onActivityCreated 函数调用定义动作的 Activity 函数以传输到其他片段。 请参考这里 [Replacing a fragment with another fragment inside activity group

    【讨论】:

    • 试过了,但我在 logcat 中遇到错误,说 No view found for id 0x7f0e0073 (com.example.samsung.drawer:id/feed_list) for fragment List_Activity{21f7eb38 #2 id=0x7f0e0073}
    • 我不清楚你的错误,但你可以在 Stackoverflow 上搜索同样的错误。请先尝试搜索,然后再提出问题。
    【解决方案4】:

    在 Fragment 之间直接通信不是一个好习惯,您应该只通过使用 Interface 设计模式的 Activity 在它们之间进行通信。这是我之前的一篇文章中的link,描述了如何实现它。

    【讨论】:

    • 谁对这个精彩的答案投了反对票?投反对票是没有意义的,你必须给它一个理由!
    【解决方案5】:

    试试这个方法

    private void startLisActivity(RSSFeed feed) {
        Bundle bundle = new Bundle();
        bundle.putSerializable("feed", feed);
        List_Activity fragment = new List_Activity();
        fragment.setArguments(bundle);
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.frame_container, fragment).commit();
        getActivity().finish();
    }
    

    其中frame_container 是您要替换FragmentFrameLayout 的ID。 希望对你有帮助!

    【讨论】:

    • 我在feed = (RSSFeed) getActivity().getIntent().getExtras().get("feed"); in List_activity 的某处遇到空指针异常错误...
    • 这是一个包含所有已解析的Item的类
    • 你可以发布RSSFeed课程吗?
    • 使用 RSSItem 发布 RSSFeed
    • 我认为您需要检查如何通过 bundle 传递自定义类对象,它将解决您的问题。我已经给出了如何将数据从一个片段传递到另一个片段的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多