看板 KnucklesNote
作者 標題 [AndroidStudio] 建立文章編輯器
時間 2016-07-26 Tue. 18:40:21
設計一個像這樣的文章編輯器
![[圖]](http://i.imgur.com/dmWPFhw.png)
在res/layout/新增 activity_editor.xml
建立標題與內文的輸入框
用 Design 模式看會像這樣
![[圖]](http://i.imgur.com/3PUYde0.png)
用 XML 文字模式的內容為
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="標題:"
android:id="@+id/titleTextView"
android:textSize="20sp" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/titleEditText"
android:textSize="20sp"
android:inputType="text" />
</LinearLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/textEditText"
android:layout_gravity="center_horizontal"
android:background="@android:color/white"
android:textColor="@android:color/black"
android:textSize="20sp"
android:gravity="top"
android:inputType="textMultiLine" />
</LinearLayout>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="標題:"
android:id="@+id/titleTextView"
android:textSize="20sp" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/titleEditText"
android:textSize="20sp"
android:inputType="text" />
</LinearLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/textEditText"
android:layout_gravity="center_horizontal"
android:background="@android:color/white"
android:textColor="@android:color/black"
android:textSize="20sp"
android:gravity="top"
android:inputType="textMultiLine" />
</LinearLayout>
</LinearLayout>
在java/新增 EditorActivity.java
將 public class EditorActivity { }
修改為
public class EditorActivity extends AppCompatActivity {
//會用到的成員變數
private int mBoardId; //看板ID,要從發文的看板傳過來
private EditText mTitleEditText;
private EditText mTextEditText;
private ProgressDialog mLoadingDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 設定要顯示回上一頁的按鈕
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
//接收intent傳來的資料
Bundle args = this.getIntent().getExtras();
mBoardId = args.getInt("bi");
mTitleEditText = (EditText) findViewById(R.id.titleEditText);
mTextEditText = (EditText) findViewById(R.id.textEditText);
}
}
//會用到的成員變數
private int mBoardId; //看板ID,要從發文的看板傳過來
private EditText mTitleEditText;
private EditText mTextEditText;
private ProgressDialog mLoadingDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 設定要顯示回上一頁的按鈕
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
//接收intent傳來的資料
Bundle args = this.getIntent().getExtras();
mBoardId = args.getInt("bi");
mTitleEditText = (EditText) findViewById(R.id.titleEditText);
mTextEditText = (EditText) findViewById(R.id.textEditText);
}
}
修改 AndroidManifest.xml 在 <application> 裡增加一個 <activity>
<activity
android:name=".EditorActivity"
android:label="@string/activity_editor"
android:configChanges="screenSize|orientation"
android:windowSoftInputMode="adjustResize"
android:parentActivityName=".TextListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".TextListActivity" />
</activity>
android:name=".EditorActivity"
android:label="@string/activity_editor"
android:configChanges="screenSize|orientation"
android:windowSoftInputMode="adjustResize"
android:parentActivityName=".TextListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".TextListActivity" />
</activity>
其中加上了 android:windowSoftInputMode="adjustResize"
讓虛擬鍵盤出現時,頁面會自動調整高度
在文章列表的選單加上發表文章的按鈕
參考 [AndroidStudio] 加入 Google 提供的 Material icons - KnucklesNote板 - Disp BBS
在 res/ 裡貼上 Create、Send 的圖示
![[圖]](http://i.imgur.com/aozZuNF.png)
![[圖]](http://i.imgur.com/bIcLIG5.png)
在 menu_textlist.xml 加上
<item
android:id="@+id/action_post"
android:icon="@drawable/ic_create_white_48dp"
android:title="@string/action_textlist_post"
app:showAsAction="ifRoom"/>
對 @string/action_textlist_post 按alt+Enter,加上字串「發表文章」android:id="@+id/action_post"
android:icon="@drawable/ic_create_white_48dp"
android:title="@string/action_textlist_post"
app:showAsAction="ifRoom"/>
加上點擊按鈕後會進入文章編輯頁
修改 TextListActivity.java 的成員函式 onOptionsItemSelected
在 switch 裡加上
case R.id.action_post:
textPost();
return true;
textPost();
return true;
在 TextListActivity.java 新增成員函式 textPost()
//發表文章
private void textPost() {
Intent editorIntent = new Intent(this, EditorActivity.class);
editorIntent.putExtra("bi", mBoardId);
startActivity(editorIntent);
}
會將看板的ID傳送過去private void textPost() {
Intent editorIntent = new Intent(this, EditorActivity.class);
editorIntent.putExtra("bi", mBoardId);
startActivity(editorIntent);
}
修改一下模擬器的設定
在「Show Advance Settings」裡的「Enable keyboard input」不要勾
![[圖]](http://i.imgur.com/RRn19TW.png)
這樣點擊輸入框時才會出現虛擬鍵盤
執行看看
![[圖]](http://i.imgur.com/Szdisv2.png)
加上送出文章的按鈕
在 /res/menu/ 新增 menu_editor.xml
內容修改為
<menu 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"
tools:context="com.disp_tech.dispbbs.EditorActivity">
<!-- 有位置的話在上方顯示為圖示-->
<item
android:id="@+id/action_send"
android:icon="@drawable/ic_send_white_48dp"
android:title="@string/action_editor_send"
app:showAsAction="ifRoom"/>
</menu>
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.disp_tech.dispbbs.EditorActivity">
<!-- 有位置的話在上方顯示為圖示-->
<item
android:id="@+id/action_send"
android:icon="@drawable/ic_send_white_48dp"
android:title="@string/action_editor_send"
app:showAsAction="ifRoom"/>
</menu>
對 @string/action_editor_send 按 alt+enter,輸入字串名稱為「送出」
在 EditorActivity.java 新增以下成員函式
private void textSend(){
//送出文章的程式
Log.d("editor","click send button");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_editor, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_send: //點了送出
textSend();
return true;
}
return super.onOptionsItemSelected(item);
}
//送出文章的程式
Log.d("editor","click send button");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_editor, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_send: //點了送出
textSend();
return true;
}
return super.onOptionsItemSelected(item);
}
執行看看,點右上角的送出按鈕
![[圖]](http://i.imgur.com/S9D9WMe.png)
在 logcat 應該會出現 "editor: click send button"
繼續完成送出文章的程式
在 EditorActivity.java 新增這幾個成員函式
@Override
protected void onDestroy() {
dismissLoadingDialog();
super.onDestroy();
}
private void showLoadingDialog(){
if(mLoadingDialog==null){
mLoadingDialog = new ProgressDialog(this);
mLoadingDialog.setMessage("傳送中...");
}
mLoadingDialog.show();
}
private void dismissLoadingDialog(){
if(mLoadingDialog!=null) {
mLoadingDialog.dismiss();
}
}
用來顯示以及關閉"傳送中..."的圖示protected void onDestroy() {
dismissLoadingDialog();
super.onDestroy();
}
private void showLoadingDialog(){
if(mLoadingDialog==null){
mLoadingDialog = new ProgressDialog(this);
mLoadingDialog.setMessage("傳送中...");
}
mLoadingDialog.show();
}
private void dismissLoadingDialog(){
if(mLoadingDialog!=null) {
mLoadingDialog.dismiss();
}
}
修改成員函式 sendText() 為
private void sendText(){
//送出文章的程式
//Log.d("editor","click send button");
String titleString = mTitleEditText.getText().toString();
String textString = mTextEditText.getText().toString();
String urlString = "http://disp.cc/api/editor.php?act=save&type=new&bi="+mBoardId;
showLoadingDialog();
AsyncHttpClient client = new AsyncHttpClient();
PersistentCookieStore cookieStore = new PersistentCookieStore(this);
client.setCookieStore(cookieStore);
RequestParams params = new RequestParams();
params.put("title", titleString);
params.put("text", textString);
client.post(urlString, params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
dismissLoadingDialog();
if (!response.optBoolean("isSuccess")) {
Toast.makeText(getApplicationContext(), "Error:" + response.optString("errorMessage"), Toast.LENGTH_LONG).show();
return;
}
//送出文章成功
finish();
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject error) {
dismissLoadingDialog();
Toast.makeText(getApplicationContext(), "Error: " + statusCode + " " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
//送出文章的程式
//Log.d("editor","click send button");
String titleString = mTitleEditText.getText().toString();
String textString = mTextEditText.getText().toString();
String urlString = "http://disp.cc/api/editor.php?act=save&type=new&bi="+mBoardId;
showLoadingDialog();
AsyncHttpClient client = new AsyncHttpClient();
PersistentCookieStore cookieStore = new PersistentCookieStore(this);
client.setCookieStore(cookieStore);
RequestParams params = new RequestParams();
params.put("title", titleString);
params.put("text", textString);
client.post(urlString, params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
dismissLoadingDialog();
if (!response.optBoolean("isSuccess")) {
Toast.makeText(getApplicationContext(), "Error:" + response.optString("errorMessage"), Toast.LENGTH_LONG).show();
return;
}
//送出文章成功
finish();
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject error) {
dismissLoadingDialog();
Toast.makeText(getApplicationContext(), "Error: " + statusCode + " " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
測試看看發表文章
按送出後回到文章列表,但發現沒有顯示新的文章
要按一下重新整理才會出現
修改一下程式,要在編輯器回到文章列表時會自動重新整理
修改 TextListActivity.java
新增成員變數
//requestCode 用來分辨是從哪個 Activity 回來
final int EDITOR_ACTIVITY = 0;
final int EDITOR_ACTIVITY = 0;
修改成員函式 textPost()
將 startActivity(editorIntent); 改成
startActivityForResult(editorIntent, EDITOR_ACTIVITY);
新增成員函式 onActivityResult()
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) { return; }
switch(requestCode) {
case EDITOR_ACTIVITY:
onRefresh(); //從 EditorActivity 回來時重新整理
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) { return; }
switch(requestCode) {
case EDITOR_ACTIVITY:
onRefresh(); //從 EditorActivity 回來時重新整理
break;
}
}
修改 EditorActivity.java
修改成員函式 sendText()
在 finish(); 這行前加上
Intent resultIntent = new Intent();
setResult(RESULT_OK, resultIntent);
setResult(RESULT_OK, resultIntent);
執行看看
新增文章回到列表後,會顯示剛剛發表的文章了
參考
https://guides.codepath.com/android/Working-with-the-Soft-Keyboard
--
※ 作者: Knuckles 時間: 2016-07-26 18:40:21
※ 編輯: Knuckles 時間: 2016-09-19 12:56:12
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 381
回列表(←)
分享