一、说在前面
1、昨天完成了:
1)历史记录的增删,展示。
2、今天完成了:
1)优化新闻详情界面(原来是用一个简单的textView控件来展示整个新闻文本,没有分段,换行等不美观!)现在改用webView展示新闻文本(实质是一个div)。
3、明天的计划:
1)实现用户对新闻评论的存储,和回显。
二、冲刺成果:
原来和现在对比:
三、设计思路
1、根据从新闻列表中获取的新闻的url网址,获取到整个新闻的html代码。
2、使用jsoup解析这段html代码找出正文所在的div并使用webView来展示。
四、代码
1、更新后的ui界面
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".NewsActivity"> <com.me.view.MyImageView android:id="@+id/iv_new_dg" android:layout_width="match_parent" android:layout_height="150dp" android:scaleType="fitXY" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.05" /> <ScrollView android:id="@+id/scrollView2" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/iv_new_dg"> <WebView android:id="@+id/wv_zw" android:layout_width="match_parent" android:layout_height="wrap_content" /> </ScrollView> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="150dp" android:orientation="horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="1.0" > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/comment_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:layout_marginBottom="50dp" /> <LinearLayout android:id="@+id/rl_enroll" android:layout_width="match_parent" android:layout_height="60dp" android:orientation="horizontal" android:layout_alignParentBottom="true" android:background="#ffffff"> <ImageView android:id="@+id/comment" android:layout_width="32dp" android:layout_height="32dp" android:src="@drawable/comment" android:layout_weight="1" android:layout_gravity="center" /> <ImageView android:id="@+id/chat" android:layout_width="23dp" android:layout_height="23dp" android:src="@drawable/chat" android:layout_weight="1" android:layout_gravity="center"/> </LinearLayout> <RelativeLayout android:id="@+id/rl_comment" android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffff" android:visibility="gone" android:layout_alignParentBottom="true"> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#969696" /> <TextView android:id="@+id/hide_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="隐藏" android:textSize="13sp" android:textColor="#E91E63" android:drawableBottom="@drawable/hide_dowm" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp"/> <View android:layout_width="1dp" android:layout_height="match_parent" android:background="#969696" android:layout_toRightOf="@id/hide_down" android:layout_marginLeft="10dp"/> <EditText android:id="@+id/comment_content" android:hint="评论" android:textSize="15sp" android:singleLine="true" android:layout_width="240dp" android:layout_height="match_parent" android:background="@null" android:layout_toRightOf="@id/hide_down" android:layout_marginLeft="20dp"/> <Button android:id="@+id/comment_send" android:layout_width="50dp" android:layout_height="35dp" android:layout_margin="5dp" android:text="发送" android:textSize="13sp" android:textColor="#ffffff" android:background="#E91E63" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginLeft="15dp"/> </RelativeLayout> </RelativeLayout> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
2、发送url请求的工具类
package com.me.util; import android.util.Log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; public class HttpUtil { /** * 返回json * * @param setUrl * @return */ public static String setUrl(String setUrl) { try { URL url = new URL(setUrl); setUrl = URLEncoder.encode(setUrl, "utf-8"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); // conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br"); int responseCode = conn.getResponseCode(); Log.e("web", responseCode + "aa"); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader reader = new BufferedReader(inputStreamReader); StringBuffer stringBuffer = new StringBuffer(); String string = reader.readLine(); while (string != null) { stringBuffer.append(string); string = reader.readLine(); } Log.e("web", stringBuffer.toString()); return stringBuffer.toString(); } else { Log.e("web", responseCode + "aa"); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return ""; } public static String setUrlT(String setUrl) { try { URL url = new URL(setUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader reader = new BufferedReader(inputStreamReader); StringBuffer stringBuffer = new StringBuffer(); String string = reader.readLine(); while (string != null) { stringBuffer.append(string); string = reader.readLine(); } Log.e("web", stringBuffer.toString()); return stringBuffer.toString(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return ""; } }
3、相应的逻辑代码:
package com.me.news_2; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.me.adapter.AdapterComment; import com.me.domain.Comment; import com.me.domain.New_; import com.me.domain.News; import com.me.util.HttpUtil; import com.me.util.JsoupNewsUtil; import com.me.view.MyImageView; import java.util.ArrayList; import java.util.List; public class NewsActivity extends AppCompatActivity implements View.OnClickListener{ private MyImageView imageView; private WebView zw; private LinearLayout linearLayout; private ImageView comment; private ImageView chat; private TextView hide_down; private EditText comment_content; private Button comment_send; private SentUrlTask sentUrlTask; private SentUrlTask_ sentUrlTask_; private SentUrlTask_getComment sentUrlTask_getComment; private LinearLayout rl_enroll; private RelativeLayout rl_comment; private ListView comment_list; private AdapterComment adapterComment; private List<Comment> data; private New_ new_2 = new New_(); private String html; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_news); initView(); action(); } private class SentUrlTask extends AsyncTask<Void,Void,String> { private String url; public SentUrlTask(String url) { this.url = url; } @Override protected String doInBackground(Void... voids) { return HttpUtil.setUrlT(url); } @Override protected void onPostExecute(@NonNull String s) { super.onPostExecute(s); html = JsoupNewsUtil.zwHtml(s); zw.loadData(html,"text/html;charset=utf-8",null); } } public void initView(){ imageView = findViewById(R.id.iv_new_dg); zw = findViewById(R.id.wv_zw); linearLayout = findViewById(R.id.linearLayout); // 初始化评论列表 comment_list = findViewById(R.id.comment_list); // 初始化数据 if (data==null){ data = new ArrayList<>(); } // 初始化适配器 adapterComment = new AdapterComment(getApplicationContext(), data); // 为评论列表设置适配器 comment_list.setAdapter(adapterComment); comment = findViewById(R.id.comment); hide_down = findViewById(R.id.hide_down); comment_content = findViewById(R.id.comment_content); comment_send = findViewById(R.id.comment_send); rl_enroll = findViewById(R.id.rl_enroll); rl_comment = findViewById(R.id.rl_comment); chat = findViewById(R.id.chat); setListener(); } /** * 设置监听 */ public void setListener(){ comment.setOnClickListener(this); hide_down.setOnClickListener(this); comment_send.setOnClickListener(this); chat.setOnClickListener(this); } public void action(){ Intent intent = getIntent(); String news = intent.getStringExtra("news"); Gson gson = new Gson(); New_ news1 = gson.fromJson(news, New_.class); new_2 = news1; getComment(new_2.getId()); if(news1!=null){ sentUrlTask = new SentUrlTask(news1.getUrl()); sentUrlTask.execute(); imageView.setImageURL(news1.getImgsrc()); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.comment: // 弹出输入法 InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); // 显示评论框 rl_enroll.setVisibility(View.GONE); rl_comment.setVisibility(View.VISIBLE); break; case R.id.hide_down: // 隐藏评论框 rl_enroll.setVisibility(View.VISIBLE); rl_comment.setVisibility(View.GONE); // 隐藏输入法,然后暂存当前输入框的内容,方便下次使用 InputMethodManager im = (InputMethodManager)getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE); im.hideSoftInputFromWindow(comment_content.getWindowToken(), 0); break; case R.id.comment_send: sendComment(); break; case R.id.chat: if(View.GONE==comment_list.getVisibility()){ comment_list.setVisibility(View.VISIBLE); // linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,200)); }else{ comment_list.setVisibility(View.GONE); // linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,60)); } default: break; } } /** * 发送评论 */ public void sendComment() { if (comment_content.getText().toString().equals("")) { Toast.makeText(getApplicationContext(), "评论不能为空!", Toast.LENGTH_SHORT).show(); } else { sent("笑天",comment_content.getText().toString(),new_2.getId()); // 生成评论数据 Comment comment = new Comment(); comment.setName("笑天" + ":"); comment.setContent(comment_content.getText().toString()); adapterComment.addComment(comment); // 发送完,清空输入框 comment_content.setText(""); Toast.makeText(getApplicationContext(), "评论成功!", Toast.LENGTH_SHORT).show(); } } public void sent(String name,String content,int nid){ sentUrlTask_ = new SentUrlTask_("http://192.168.1.17:8080/NewsApi/news?method=addComment&name="+name+"&content="+content+"&nid="+nid); // sentUrlTask = new ListFragment.SentUrlTask("http://192.168.43.243:8080/NewsApi/news?method=allnews"); sentUrlTask_.execute(); } public void getComment(int nid){ sentUrlTask_getComment = new SentUrlTask_getComment("http://192.168.1.17:8080/NewsApi/news?method=commentList&nid="+nid); // sentUrlTask = new ListFragment.SentUrlTask("http://192.168.43.243:8080/NewsApi/news?method=allnews"); sentUrlTask_getComment.execute(); } private class SentUrlTask_ extends AsyncTask<Void,Void,String> { private String url; public SentUrlTask_(String url) { this.url = url; } @Override protected String doInBackground(Void... voids) { return HttpUtil.setUrl(url); } @Override protected void onPostExecute(@NonNull String s) { super.onPostExecute(s); // zw.loadData(html,"text/html;charset=utf-8",null); } } private class SentUrlTask_getComment extends AsyncTask<Void,Void,String> { private String url; public SentUrlTask_getComment(String url) { this.url = url; } @Override protected String doInBackground(Void... voids) { return HttpUtil.setUrl(url); } @Override protected void onPostExecute(@NonNull String s) { super.onPostExecute(s); // zw.loadData(html,"text/html;charset=utf-8",null); Gson gson = new Gson(); // Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show(); if(!s.equals("")){ data = gson.fromJson(s,new TypeToken<List<Comment>>(){}.getType()); adapterComment.setData(data); } } } }