【问题标题】:How do I make a list of objects parcelable in Android?如何在 Android 中制作可打包的对象列表?
【发布时间】:2017-08-19 12:00:25
【问题描述】:

所以我有一个应用程序,它通过 API 在互联网上搜索艺术家,并在执行此搜索后显示结果列表(艺术家姓名)。我想保留此列表,因为我更改了设备的方向(纵向 - 横向),而不必再次执行搜索。这是一些代码:

public class MainActivityFragment extends Fragment{

    public static final String ARTIST_ID = "artistId";
    private final String NO_RESULTS = "No artists found. Please check your input!";

    private List<Artist> artists = new ArrayList<>();
    private ArtistArrayAdapter adapter;

    public MainActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        final SearchView searchView = (SearchView) rootView.findViewById(R.id.search_artist);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String artistName) {
                SearchArtist(artistName);
                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });

        ListView listView = (ListView) rootView.findViewById(android.R.id.list);
        adapter = new ArtistArrayAdapter(getActivity(), R.layout.artist_list_item, artists);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Artist artist = artists.get(position);
                String artistId = artist.id;
                Intent detailArtist = new Intent(getActivity(), DetailActivity.class);
                detailArtist.putExtra(ARTIST_ID, artistId);
                startActivity(detailArtist);
            }
        });

        return rootView;
    }

所以我认为我必须使艺术家列表可打包,然后将其传递给 onSaveInstanceState 方法。但是如何使这个列表可打包呢?

非常感谢,我希望这不会太混乱......

【问题讨论】:

    标签: android parcelable


    【解决方案1】:

    您需要为您的 Artist Data Model 类实现 Parcelable 接口。例如

    public class ArtistParcelable implements Parcelable {
        public String id;
        public String artistName;
        public List<String> artistImageUrls = Collections.emptyList();
    
        public ArtistParcelable(Artist artist) {
            // Do the assignments here
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            //write 
            dest.writeString(this.id);
            dest.writeString(this.artistName);
            dest.writeStringList(this.artistImageUrls);
        }
    
        protected ArtistParcelable(Parcel in) {
            //retrieve
            this.id = in.readString();
            this.artistName = in.readString();
            this.artistImageUrls = in.createStringArrayList();
        }
    
        public static final Parcelable.Creator<ArtistParcelable> CREATOR = new Parcelable.Creator<ArtistParcelable>() {
            public ArtistParcelable createFromParcel(Parcel source) {
                return new ArtistParcelable(source);
            }
    
            public ArtistParcelable[] newArray(int size) {
                return new ArtistParcelable[size];
            }
        };
    }
    

    在您的片段中 - 如果您有 List mArtists,那么您可以像

    一样保存和检索列表
    @Override
    public void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(ARTISTS, (ArrayList<? extends Parcelable>) mArtists);
    }
    

    在 onCreateView 中

    if (savedInstanceState != null) {
            mArtists = savedInstanceState.getParcelableArrayList(ARTISTS);
    

    这是一个很好的指南,您可以遵循。 https://guides.codepath.com/android/Using-Parcelable

    还有一个名为 Android Parcelable Code Generator 的 IDE 插件可用,它会为您生成所有样板代码。

    还有一个名为Parceler 的库,非常方便。它完全删除了样板。

    【讨论】:

    • 没有必要,因为如果我没记错的话,那么您将从 API 获取基本 Artist 类对象,因此即使您将 Parcelable 创建为 Artist 的子类,您' 仍然需要将您的 Artist 对象转换为 ArtistParcelable 对象。
    【解决方案2】:

    首先你的 Artist 类必须实现 parcelable

    public class Artist implements Parcelable
    

    然后你应该重写方法 writeToParcel 说你想保存什么,例如:

      @Override
            public void writeToParcel(Parcel dest, int flags) {
                dest.writeString(mSavedString);
         }
    

    创建一个构造函数来读取保存的变量:

     protected Artist(Parcel in){
        mSavedString = in.readString();
    }
    

    然后是创建者:

     public static final Parcelable.Creator<Artist> CREATOR
                 = new Parcelable.Creator<Artist>() {
             public Artist createFromParcel(Parcel in) {
                 return new Artist(in);
             }
    
             public Artist[] newArray(int size) {
                 return new Artist[size];
             }
         };
    

    最后在您的活动上覆盖 onsavedinstance:

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArray("AristArray", mArtistArray);
    }
    

    另外,不要忘记通过在您的活动的 onCreate 上执行此操作来检索:

     if (savedInstanceState != null) {
       mArtistArray= new List<Artist>(savedInstanceState.getParcelableArray("ArtistArray"));
     }
    

    Ps:没试过代码,有什么想知道的可以问,我会尽力帮助你的;)

    src:http://developer.android.com/reference/android/os/Parcelable.html

    希望对您有所帮助;)

    【讨论】:

      【解决方案3】:

      如何修改您的 Artist 类以使其成为 Parcelabel。

      public class Artist implements Parcelable {
      
          public static final Creator<Artist> CREATOR = new Creator<Artist>() {
              public Artist createFromParcel(Parcel source) {
                  return new Artist(source);
              }
      
              public Artist[] newArray(int size) {
                  return new Artist[size];
              }
          };
      
          private final String name;
      
          public Artist(String name) {
              this.name = name;
          }
      
          private Artist(Parcel in) {
              name = in.readString();
          }
      
          @Override
          public void writeToParcel(Parcel dest, int flags) {
              dest.writeString(name);
          }
      
          @Override
          public int describeContents() {
              return 0;
          }
      
          public String getName() {
              return name;
          }
      }
      

      然后使用以下。

      protected void onSaveInstanceState(Bundle outState) {
       outState.putParcelableArrayList("key_artists",artists);
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        相关资源
        最近更新 更多