偶然在一个QQ群看到有学生在问关于这个平台的事,刚好无聊就登录看了一下。刚好自己自学android到了一个瓶颈。就写了一个基于这个平台的新闻app,平台是免费,而且讲解的很详细,有时候第一次打开比较慢,多试几次等等就好了。这是平台的地址:
http://www.tngou.net/
下面是接口:
http://www.tngou.net/blog/show/1296
向提供免费平台的前辈致敬!
目前我已经实现的功能有:
读取最新的新闻列表(最近好像新闻列表很久没更新了。不过原来的能读取,用来学习已经够了)
读取新闻的内容
读取相关评论
账号注册,账号登录,个人信息设置(这里偷懒了,个人信息设置点击后直接跳转到网站去了。。。)
这个项目适合新手练习,涉及和服务端的数据交互以及数据解析。不足之处是界面比较挫,没有框架可言,所以越写到后面代码耦合度越高,逻辑比较混乱。
因为图片只能2M,所以只录了一部分。
项目构造:
Account 主要是账号登录,注册,以及个人信息修改
Adapter包含两个适配器,一个是评论列表的适配器,一个是新闻列表的适配器
GetContext 用来在像某种获取Context对象
ImageCache 图像缓存,计划用来将图片缓存到本地,就不用每次打开app都要去服务端下载图片,功能还没添加
JSON JSON数据解析
CommentsActivity 评论列表相关逻辑操作
ItemActivity 新闻内容界面相关逻辑操作
MainActivity 主题框架逻辑事件以及新闻列表逻辑事件,大部分UI刷新
RecyclerItem 新闻类 包含一条新闻的基本信息
每个类里面都有详细的注释,不多说了。下面贴出来MainActivity :
/**
* 主页 app第一页
*/
public class MainActivity extends AppCompatActivity {
private String PATH = "http://www.tngou.net/api/top/list";//热点词api,通过获取热点词汇的id获取热词详情
private RecyclerView recyclerView; //新闻列表
private DrawerLayout drawerLayout; //抽屉视图
private NavigationView navigationView; //导航视图
private SwipeRefreshLayout swipeRefreshLayout; //下拉刷新
private FloatingActionButton actionButton; //悬浮按钮
private RecyclerAdapter adapter; //新闻列表适配器
private CircleImageView circleImageView;//头像
private TextView individuality_text;//个性签名
private List<RecyclerItem> list_items = new ArrayList<>(); //新闻列表子项
private User user; //用户信息获取类
private String domain = null; //用户主页域名
// private String access_token = null;//访问令牌
private static int[] image_ID = {R.drawable.aa, R.drawable.bb, R.drawable.cc, R.drawable.dd, R.drawable.ee, R.drawable.ff, R.drawable.gg, R.drawable.hh, R.drawable.ii,
R.drawable.jj, R.drawable.kk, R.drawable.ll, R.drawable.mm, R.drawable.nn, R.drawable.bb, R.drawable.cc, R.drawable.dd, R.drawable.ee, R.drawable.ff, R.drawable.gg};
public static int get_Image_ID() { //为没有图片的新闻随机一个图片
Random random = new Random();
return image_ID[random.nextInt(image_ID.length)];
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg); //网络数据获取后通过message发送给UI线程
switch (msg.what) {
case 1: //新闻列表
JSON json = new JSON();
json.withJSONObject(msg.getData().getString("JSON_data")); //JSON数据解析
List<String> list_img = json.getImg_list(); // 新闻图片地址
List<String> list_title = json.getList_title(); //新闻标题
List<String> list_description = json.getList_description(); //新闻摘要
List<Long> list_ID = json.getList_ID(); //新闻详情地址
for (int i = 0; i < list_img.size(); i++) {
list_items.add(new RecyclerItem(list_title.get(i), list_img.get(i), list_description.get(i), list_ID.get(i)));
}
adapter.notifyDataSetChanged(); //通知适配器数据更新
break;
case 2: //显示个人信息
individuality_text.setText(user.getSignature());
Glide.with(MainActivity.this).load("http://tnfs.tngou.net/img" + user.getAvatar()).into(circleImageView);
domain = user.getDomain();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar); //设置自定义tab
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);//显示HomeAsUp键
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); //设置HomeAsUp键图标
}
drawerLayout = (DrawerLayout) findViewById(R.id.activity_main);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setCheckedItem(R.id.nav_call); //设置导航视图默认选中项
//导航视图子项事件监听
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_task://切换到账号注册
AccountOperation accountOperation = new AccountOperation(MainActivity.this, new UserLoginCallback() {
@Override
public void LoginSuccessful(String access_token, String refresh_token) { // 注册成功,反馈回access_token访问令牌 refresh_token 刷新令牌
user = new User(access_token, null, handler); // 子线程从服务器获取到用户个人信息,发送一个msg
// MainActivity.this.access_token = access_token;
}
@Override
public void loginFailed(String msg) { //注册失败服务端反馈的消息
}
});
break;
case R.id.nav_mail://切换到账号登录
AccountLogin accountLogin = new AccountLogin(MainActivity.this, new UserLoginCallback() {
@Override
public void LoginSuccessful(String access_token, String refresh_token) {//登录成功,反馈回来access_token访问令牌 refresh_token 刷新令牌
user = new User(access_token, null, handler); // 子线程从服务器获取到用户个人信息,发送一个msg
// MainActivity.this.access_token = access_token;
}
@Override
public void loginFailed(String msg) {//登录失败服务端反馈的消息
}
});
break;
}
return true;
}
});
// headerLayout = navigationView.inflateHeaderView(R.layout.nav_header_main);//加载头部view
View headerView = navigationView.getHeaderView(0);//获得头部View
circleImageView = (CircleImageView) headerView.findViewById(R.id.head_portrait);
circleImageView.setOnClickListener(new View.OnClickListener() { //点击用户头像 进入个人资料页面
@Override
public void onClick(View view) {//头像点击事件监听
if (domain == null) {//如果domain为空 则先登录
AccountLogin accountLogin = new AccountLogin(MainActivity.this, new UserLoginCallback() {
@Override
public void LoginSuccessful(String access_token, String refresh_token) {//登录成功,反馈回来access_token访问令牌 refresh_token 刷新令牌
user = new User(access_token, null, handler); // 子线程从服务器获取到用户个人信息,发送一个msg
// MainActivity.this.access_token = access_token;
}
@Override
public void loginFailed(String msg) {//登录失败服务端反馈的消息
}
});
} else {
Intent intent = new Intent(MainActivity.this, UserInformation.class);
intent.putExtra("path", "http://www.tngou.net/my/"+domain);
MainActivity.this.startActivity(intent);
}
}
});
individuality_text = (TextView) headerView.findViewById(R.id.individuality_signature);
circleImageView.setImageResource(R.drawable.bb);//默认头像
individuality_text.setText("我在等待,一个有你的未来!");//默认签名
actionButton = (FloatingActionButton) findViewById(R.id.FAButton);//悬浮按钮设置及事件监听
actionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "悬浮按钮,功能待添加", Snackbar.LENGTH_LONG).setAction("确定", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "点击悬浮按钮", Toast.LENGTH_SHORT).show();
}
}).show();
}
});
data_init(); //新闻数据初始化(包括加载网络数据)
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
adapter = new RecyclerAdapter(list_items);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);//recyclerView相关设置
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe);
swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
data_init();//下拉刷新数据
swipeRefreshLayout.setRefreshing(false);
}
});
}
public void data_init() {
HttpUtil.sendHttpRequest(PATH, new HttpCallbackListener() {//加载网络数据并将数据通过msg发送到UI线程
@Override
public void onFinish(final String response) {
Bundle bundle = new Bundle();
bundle.putString("JSON_data", response);
// Message msg = new Message();
Message msg = Message.obtain();
msg.setData(bundle);
msg.what = 1;
handler.sendMessage(msg);
}
@Override
public void onError(Exception e) {
Toast.makeText(MainActivity.this, "数据请求失败", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { //菜单选项点击监听
switch (item.getItemId()) {
case R.id.ic_backup:
Toast.makeText(this, "" + item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case R.id.ic_comment:
Toast.makeText(this, "" + item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
break;
}
return true;
}
}
整个项目上传到了github:https://github.com/Guojiankai/news
欢迎交流指正!