转载自:
作者:齐天小圣^O^
https://blog.csdn.net/h2503652646/article/details/84936337
除了布局文件,代码几乎全部是上面这篇博客的,但是在onStart方法上好像有点小问题,我改了。
一.题目
1、设计一个新闻数据库,包含一个新闻表:
表名:NewsTable
2、重写SQLiteOpenHelper类,以使第一次加载时能创建数据库及表,并insert几条初始新闻;当ListActivity加载时,读取数据库中的信息,并创建News对象序列并将数据库中的记录写入,其他程序逻辑可不修改。
3、修改新闻列表,以ListView实现,或在Layout中动态生成TextView实现,使得新闻列表可根据数据库中新闻条数多少而增减。
4、使用SharedPreferences保存已看过的新闻ID,下次再进入时,以灰色显示。
提示:可使用数组的方式存储新闻ID,存储时,可将整形数组转为逗号分隔的字符串如1,3,3,4,读取时,将读取到的字符串转为数组即可,具体转换方式可使用split和join方法实现,自行查阅资料解决;也可以用新闻ID作为键名实现存储。
二.内容
1.目录结构
一个实体类News,三个Acticity活动,一个适配器,一个数据库辅助类
由于采用listview方法,有一个模板布局文件new_item.xml
2.代码
具体过程的解释参考原博文:
https://blog.csdn.net/h2503652646/article/details/84936337
ListActivity :
public class ListActivity extends AppCompatActivity {
//新闻阅读时间
static long time1;
static long time2;
//记录新闻条数
int count=0;
//用于记录被点击的行号
String number;
ListView listView;
//已浏览过的新闻ID的集合
static List<String> idList =new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
//从数据库获取资源
//1.创建数据库,数据库名为News.db
NewsOpenHelper helper = new NewsOpenHelper(this, "News.db", null, 1);
SQLiteDatabase db = helper.getWritableDatabase();
//2.插入数据
ContentValues values = new ContentValues();
values.put("Title", "标题一");
values.put("Content", "新闻一的内容,此处省略1000字......");
values.put("Source", "新浪网");
values.put("time", "2018/11/25");
db.insert("NewsTable", null, values);
values.clear();
values.put("Title", "标题二");
values.put("Content", "新闻二的内容,此处省略1500字......");
values.put("Source", "新华网");
values.put("time", "2018/11/25");
db.insert("NewsTable", null, values);
values.clear();
values.put("Title", "标题三");
values.put("Content", "新闻三的内容,此处省略1200字......");
values.put("Source", "腾讯网");
values.put("time", "2018/11/25");
db.insert("NewsTable", null, values);
//newsList新闻集合
List<News> newsList=new ArrayList<News>();
//游标查询数据库内容
Cursor cursor=db.query("NewsTable",null,null,null,null,null,null);
//获取新闻条数
count=cursor.getCount();
int i=0;
//创建新闻数组
final News[] news=new News[count];
if(cursor.moveToFirst())
{
do{
//获取数据库中的值
int id=cursor.getInt(cursor.getColumnIndex("ID"));
String title=cursor.getString(cursor.getColumnIndex("Title"));
String content=cursor.getString(cursor.getColumnIndex("Content"));
String source=cursor.getString(cursor.getColumnIndex("Source"));
String time=cursor.getString(cursor.getColumnIndex("time"));
news[i]=new News();
news[i].setId(String.valueOf(id));
news[i].setTitle(title);
news[i].setContent(content);
news[i].setSource(source);
news[i].setTime(time);
//将每条新闻存入集合
newsList.add(news[i]);
i++;
}while(cursor.moveToNext());
}
//借用适配器ArrayAdapter来将数据传入ListView
MyAdapter adapter=new MyAdapter(ListActivity.this,R.layout.news_item,newsList);
listView=(ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
//注意:OnClickListener是监听ListView本身的点击事件,OnItemClickListener是监听ListView中子条目的点击事件
//这里使用setOnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick( AdapterView<?> parent, View view, int position, long id) {
//用Intent传输数据到DetailActivity
Intent intent = new Intent();
intent.setClassName(ListActivity.this, "com.lcl.task6.DetailActivity");
number= news[position].getId();
intent.putExtra("title", news[position].getTitle());
intent.putExtra("Source", news[position].getSource());
intent.putExtra("Time", news[position].getTime());
intent.putExtra("content", news[position].getContent());
startActivityForResult(intent, 1);
}
});
}
// 如果用onStart方法,第二次启动程序会报错
// @Override
// protected void onStart() {
// super.onStart();
// time2=System.currentTimeMillis();
// //若达到规定浏览时间,则将该新闻ID添加进存放已浏览新闻的list
// getAlRead();
// //判断新闻是否已经浏览,若是,则将标题颜色置灰
// changeColor();
// }
@Override
public void onRestart(){
super.onRestart();
time2=System.currentTimeMillis();
//若达到规定浏览时间,则将该新闻ID添加进存放已浏览新闻的list
getAlRead();
//判断新闻是否已经浏览,若是,则将标题颜色置灰
changeColor();
}
private void getAlRead()
{
//达到规定阅读时间,则将新闻ID存入文件
if((time2-time1)/1000>3 && time1!= 0) {
SharedPreferences.Editor editor = getSharedPreferences("AlRead", MODE_PRIVATE).edit();
idList.add(number);
//将已读新闻ID转化为字符串保存,以逗号分隔
String str = "";
for (int i = 0; i < idList.size(); i++) {
str += idList.get(i) + ",";
}
editor.putString("data", str);
editor.apply();
}
}
private void changeColor()
{
//获取文件
File file=new File("data/data/com.lcl.task6/shared_prefs","AlRead.xml");
//如果文件存在,则将文件内id对应的新闻置灰
if(file.exists())
{
SharedPreferences pref=getSharedPreferences("AlRead", MODE_PRIVATE);
String str=pref.getString("data","");
//将字符串以“,”分割为字符串数组sstr
String sstr[]=str.split("[,]");
//再将字符串数组存入lstAlRead
List<String> lstAlRead=new ArrayList<String>();
for (int i=0; i < sstr.length; i++) {
if(!lstAlRead.contains(sstr[i])) {
lstAlRead.add(sstr[i]);
}
}
//将lstAlRead中的新闻ID置灰
for(int i=0; i<lstAlRead.size(); i++)
{
// 获得子条目item的layout
LinearLayout layout = (LinearLayout)listView.getChildAt(Integer.valueOf(lstAlRead.get(i))-1);
TextView title = (TextView) layout.findViewById(R.id.title1);
title.setTextColor(Color.GRAY);
}
}
}
}
注意:如果用onStart方法,第二次启动程序会报错
本人才疏学浅,看了半天也没弄清楚,代码没有一点错,大概是Activity生命周期顺序的原因,导致操作对象为空
NewsOpenHelper:
public class NewsOpenHelper extends SQLiteOpenHelper {
//定义表,表名:NewsTable
public final String CREATE_NEWS = "create table NewsTable(" +
"ID integer primary key autoincrement," +
"Title text," +
"Content text,"+
"Source text," +
"time text)";
public NewsOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//创建表
sqLiteDatabase.execSQL(CREATE_NEWS);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
MyAdapter :
public class MyAdapter extends ArrayAdapter<News> {
//每行新闻的布局
private int resourceId;
public MyAdapter(Context context, int resource, List<News> objects) {
super(context, resource, objects);
resourceId=resource;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获取当前项的实例
News myNew=getItem(position);
//利用convertView缓存提高ListView效率
View view;
if(convertView==convertView)
{
view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
}else
{
view=convertView;
}
//获取对应控件实例并赋值
TextView tvTitle1=(TextView) view.findViewById(R.id.title1);
tvTitle1.setText(myNew.getTitle());
tvTitle1.setTextColor(Color.BLACK);
TextView tvTitle2=(TextView) view.findViewById(R.id.Source1);
tvTitle2.setText("来源:"+myNew.getSource());
TextView tvTitle3=(TextView) view.findViewById(R.id.Time1);
tvTitle3.setText("时间:"+myNew.getTime());
// ImageView ivTitle=(ImageView) view.findViewById(R.id.imageView);
// ivTitle.setImageResource(myNew.getImageSource());
return view;
}
}
DetailActivity :
public class DetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Intent intent=getIntent();
TextView title=(TextView)findViewById(R.id.title);
title.setText(intent.getStringExtra("title"));
TextView source=(TextView)findViewById(R.id.Source);
source.setText(intent.getStringExtra("Source"));
TextView time=(TextView)findViewById(R.id.Time);
time.setText(intent.getStringExtra("Time"));
TextView content=(TextView)findViewById(R.id.content);
content.setText(intent.getStringExtra("content"));
}
@Override
protected void onStart() {
super.onStart();
ListActivity.time1 = System.currentTimeMillis();
}
}
News:
public class News {
public String Id;
public String title;
public String content;
public String Source;
public String Time;
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSource() {
return Source;
}
public void setSource(String source) {
Source = source;
}
public String getTime() {
return Time;
}
public void setTime(String time) {
Time = time;
}
}
3.布局文件
activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
news_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"
>
<!-- <ImageView-->
<!-- android:layout_gravity="center_vertical"-->
<!-- android:id="@+id/userPic"-->
<!-- android:layout_width="60dp"-->
<!-- android:layout_height="60dp"-->
<!-- android:src="@drawable/newspic"-->
<!-- ></ImageView>-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginLeft="5dp">
<TextView
android:id="@+id/title1"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:text="新闻标题1"
android:textSize="20sp"
android:textStyle="bold"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/Source1"
android:text="来源:新华网 "
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical">
</TextView>
<TextView
android:id="@+id/Time1"
android:text="时间:2020/10/02"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#336BE3">
</View>
</LinearLayout>
效果: