【问题标题】:How to split passed ListView item in another intent?如何在另一个意图中拆分传递的 ListView 项目?
【发布时间】:2016-12-28 17:10:52
【问题描述】:

我是 android 和 java 的新手,我在这个 android 项目上工作,在那里我有一个 ListView 的电影(名称-字符串、流派-字符串、年份-整数)。我想在将 Item 传递给另一个 activity 后拆分它。

我的电影模特:

public class Movie
{
    // property to help us handle the data
    private int id;
    private String name;
    private String genre;
    private int year;


    //Getters and Setters of the properties
    public long getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }


    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }


    public String getGenre()
    {
        return genre;
    }

    public void setGenre(String genre)
    {
        this.genre = genre;
    }


    public int getYear()
    {
        return year;
    }

    public void setYear(int year)
    {
        this.year = year;
    }


    public String toString()
    {
        return name + ", " + genre + ", " + year;
    }



//----------Start--------- Here we have defined the table contents (basically a blueprint of the table Movie) -------------------------------------

    public static final String TABLE_NAME = "movie";
    public static final String COlUMN_ID = "id";
    public static final String COlUMN_NAME = "make";
    public static final String COlUMN_GENRE = "model";
    public static final String COlUMN_YEAR = "year";

//----------------------END----------------------------------------------------------------------------------------------------------------//

}

我的创建电影活动:

 public class CreateMovieActivity extends AppCompatActivity
{
    MoviesRepository moviesRepository;

    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_movie);

        moviesRepository = new MoviesRepository(this);
        moviesRepository.open();
    }

    public void onClickSaveMovie(View v)
    {
        Button buttonAdd = (Button) v;

        EditText editTextName = (EditText) findViewById(R.id.editTextName);
        EditText editTextGenre = (EditText) findViewById(R.id.editTextGenre);
        EditText editTextYear = (EditText) findViewById(R.id.editTextYear);

        Movie movie = new Movie();
        movie.setName(editTextName.getText().toString());
        movie.setGenre(editTextGenre.getText().toString());
        movie.setYear(Integer.parseInt(editTextYear.getText().toString()));


        moviesRepository.Create(movie);


        Button buttonCreate = (Button) v;
        startActivity(new Intent(getBaseContext(),MainActivity.class));
    }

}

我的电影存储库:

public class MoviesRepository
{
    private SQLiteDatabase db;
    private MyDBHelper myDBHelper;


    private String [] MovieAllColumns ={Movie.COlUMN_ID,
            Movie.COlUMN_NAME,
            Movie.COlUMN_GENRE,
            Movie.COlUMN_YEAR};



    public MoviesRepository(Context context)
    {
        myDBHelper = new MyDBHelper(context);
    }


    public void open() throws SQLException
    {
        //Open connection to write data
        db = myDBHelper.getWritableDatabase();
    }


    public void close()
    {
        //Close connection to database
        db.close();
    }

    private Movie cursorToMovie (Cursor cursor)
    {
        Movie movie = new Movie();
        movie.setId(cursor.getInt(0));
        movie.setName(cursor.getString(1));
        movie.setGenre(cursor.getString(2));
        movie.setYear(cursor.getInt(3));

        return movie;
    }

    public List<Movie> getAllMovies()
    {
        open();

        List<Movie> movieList = new ArrayList<>();
        Cursor cursor = db.query(Movie.TABLE_NAME, MovieAllColumns, null, null, null, null, null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast())
        {
            Movie movie = cursorToMovie(cursor);
            movieList.add(movie);
            cursor.moveToNext();
        }

        cursor.close();
        close();
        return movieList;

    }



    public void Create(Movie movie)
    {
        open();

        //helps you insert values to the table
        ContentValues values = new ContentValues();

        //Put method - first column; what column do you want to be storing this ind. Second; what is the value you want to put ind
        values.put(Movie.COlUMN_NAME, movie.getName());
        values.put(Movie.COlUMN_GENRE, movie.getGenre());
        values.put(Movie.COlUMN_YEAR, movie.getYear());

        db.insert(Movie.TABLE_NAME, null, values);
        close();
    }


    public void Delete(Movie movie)
    {
        open();
        //Deletes Movie by id
        db.delete(Movie.TABLE_NAME, Movie.COlUMN_ID + " = " + movie.getId(), null);
        db.close();
    }

}

当我点击ListView 上的一个项目时,它会将值传递给另一个Activity,我可以将其打印出来(烤面包)。

这是我将项目传递给另一个意图的地方:

 public void Select()
    {
        moviesRepository = new MoviesRepository(this);
        moviesRepository.open();

        final Movie movie;

        final ListView listView = (ListView) findViewById(R.id.ListViewMovie);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                final String details = listView.getAdapter().getItem(position).toString();
                Intent i = new Intent(getApplicationContext(), MovieDetailsActivity.class);
                i.putExtra("key", details);
                startActivity(i);

            }
        });

    } 

但是如何将传递的值从ListView 中拆分出来,这样才有意义。

这是我想将其拆分为三个值的地方,电影名称、电影类型和年份:

public class MovieDetailsActivity extends AppCompatActivity
{
    TextView movieName;
    TextView movieGenre;
    TextView movieYear;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.movie_details);
        getDetails();
    }
    public void getDetails()
    {
        movieName = (TextView) findViewById(R.id.textViewMovieName);
        movieGenre = (TextView) findViewById(R.id.textViewMovieGenre);
        movieYear = (TextView) findViewById(R.id.textViewMovieYear);

        String data = getIntent().getExtras().getString("key");


        Toast.makeText(this, data, Toast.LENGTH_LONG).show();


    }
}

现在我只是用传递的项目干杯

【问题讨论】:

    标签: java android listview android-intent


    【解决方案1】:

    创建一个 moviemanager 单例类并具有 map。将您的电影另存为 &lt;String, Movie&gt; 到地图中。然后就可以调用Moviemanager.getInstance().getMovie(key)获取电影对象了。

    【讨论】:

    • 我想通了,但我想知道如何将数据从数据库 (SqlLite) 传递到另一个意图。或者如何将发送字符串对象与数据库中的数据进行比较?这样我就可以获得该行的所有列。
    • 正如我所说,您为此创建了一个管理器类。您必须使用数据库中的数据初始化此管理器。然后,您可以像以前一样将密钥从您的活动发送到另一个活动。在您的第二个活动中,您可以要求经理为传递的密钥获取正确的电影。您的经理和您的数据库此时具有相同的数据。这就是我在我的应用程序中所做的方式。
    【解决方案2】:

    您在询问如何拆分您在详细信息屏幕中收到的字符串。

    其实很简单;-)

    在您的MovieDetailsActivity#getDetails 中,当您从Intent 获取详细信息字符串时,您需要执行以下操作:

    String data = getIntent().getExtras().getString("key");
    String[] splitMovieString = data.split(", ");
    

    然后你可以像这样设置你的TextViews:

    movieName.setText(splitMovieString[0]);
    movieGenre.setText(splitMovieString[1]);
    movieYear.setText(splitMovieString[2]);
    

    附带说明:

    您通过Intent 将数据作为字符串发送的方法是可以的,但它不是Android 中在活动之间传递数据的首选方式。

    有一种方法可以传递整个Movie 对象,但前提是您将对象更改为实现Parcelable 接口。 (见the official documentation for a full example

    实现Parcelable 后,您的Movie 对象将如下所示:

    public class Movie implements Parcelable {
        private int id;
        private String name;
        private String genre;
        private int year;
    
        protected Movie(Parcel in) {
            id = in.readInt();
            name = in.readString();
            genre = in.readString();
            year = in.readInt();
        }
    
        public static final Creator<Movie> CREATOR = new Creator<Movie>() {
            @Override
            public Movie createFromParcel(Parcel in) {
                return new Movie(in);
            }
    
            @Override
            public Movie[] newArray(int size) {
                return new Movie[size];
            }
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeInt(id);
            parcel.writeString(name);
            parcel.writeString(genre);
            parcel.writeInt(year);
        }
    
       [... Setters, getters and your constants are removed for brevity]
    } 
    

    现在,在您稍微更改模型后,您可以像这样直接通过Intent 系统传递它:

    OnClickListener 内的Select 方法中,您需要稍微更改一下Intent

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final Movie selectedMovie = listView.getAdapter().getItem(position);
        Intent detailsIntent = new Intent(getApplicationContext(), MovieDetailsActivity.class);
        detailsIntent.putExtra(Movie.class.getName(), selectedMovie);
        startActivity(detailsIntent);
    }
    

    这里发生的情况是,我们基本上将Movie 对象“展平”(或序列化)为可以通过Intent 系统发送的对象。 现在,当您在 MovieDetailsActivity#getDetails 中收到 Intent 时,您需要再次解开(或反序列化)“扁平化”Movie 对象,以便可以像使用普通 Movie 对象一样使用它。

    所以现在你的MovieDetailsActivity#getDetails 应该是这样的:

    public void getDetails() {
        movieName = (TextView) findViewById(R.id.textViewMovieName);
        movieGenre = (TextView) findViewById(R.id.textViewMovieGenre);
        movieYear = (TextView) findViewById(R.id.textViewMovieYear);
    
        Movie movie = getIntent().getParcelableExtra(Movie.class.getName());
        // Now you can set your movie name, genre and year directly from your object.
        movieName.setText(movie.getName());
        movieGenre.setText(movie.getGenre());
        movieYear.setText(String.valueOf(movie.getYear()); // Notice you cannot set an Integer directly as the text of a `TextView`, you need to parse it as a String first.
    }
    

    我知道最后一个解决方案会给你的类带来更多的代码,但这确实是最好的方法,当你让你的模型类实现 Parcelable 接口时,Android Studio 会告诉你你错过了实施并实际询问您在实施Parcelable 方面是否需要帮助,因此您不必自己做太多事情。

    作为最后一点,还有另一种解决方案,就是将当前Movieid 传递给Intent,然后直接在MovieDetailsActivity 中从MoviesRepository 中获取,但是你会还必须使用可以从您的存储库中获取单个 Movie 的新方法来扩展您的 MoviesRepository

    我知道这是一个很长的答案,但这里有很多概念需要注意:-)

    【讨论】:

      猜你喜欢
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多