Commit eaff56ca by Author name

3.26博客markdown编辑器完成

parent b413e1b3
...@@ -74,4 +74,8 @@ dependencies { ...@@ -74,4 +74,8 @@ dependencies {
implementation 'com.facebook.fresco:webpsupport:0.12.0' implementation 'com.facebook.fresco:webpsupport:0.12.0'
implementation 'com.github.tiagohm.MarkdownView:library:0.19.0' implementation 'com.github.tiagohm.MarkdownView:library:0.19.0'
implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.5.0' implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.5.0'
implementation "io.noties.markwon:core:4.3.0"
implementation "io.noties.markwon:editor:4.3.0"
implementation "io.noties.markwon:ext-tables:4.3.0"
implementation "io.noties.markwon:image-glide:4.3.0"
} }
package cn.yunliyunwai.beyondclouds.ui.page; package cn.yunliyunwai.beyondclouds.ui.page;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import cn.yunliyunwai.beyondclouds.R; import cn.yunliyunwai.beyondclouds.R;
import cn.yunliyunwai.beyondclouds.databinding.ActivityPublishBlogBinding; import cn.yunliyunwai.beyondclouds.databinding.ActivityPublishBlogBinding;
import cn.yunliyunwai.beyondclouds.ui.page.markdown.MarkdownButtonEnum;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.editor.MarkwonEditor;
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
public class PublishBlogActivity extends AppCompatActivity { public class PublishBlogActivity extends AppCompatActivity {
...@@ -19,7 +41,195 @@ public class PublishBlogActivity extends AppCompatActivity { ...@@ -19,7 +41,195 @@ public class PublishBlogActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
binding = ActivityPublishBlogBinding.inflate(getLayoutInflater()); binding = ActivityPublishBlogBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
//创建fragment的集合
List<Fragment> list = new ArrayList<>();
list.add(new PictureFragment());
list.add(new EmojiFragment());
list.add(new FontFragment());
list.add(new OtherFragment());
list.add(new MoreFragment());
//所有头部图片的集合
List<Integer> tabImages = new ArrayList<>();
tabImages.add(R.drawable.photo_choose);
tabImages.add(R.drawable.emj_choose);
tabImages.add(R.drawable.font_choose);
tabImages.add(R.drawable.other_choose);
tabImages.add(R.drawable.more_choose);
binding.blogToolBar.setAdapter(new PublishQuestionViewPagerAdapter(getSupportFragmentManager(), this, list, tabImages));
binding.blogTabLayout.setupWithViewPager(binding.blogToolBar);
binding.blogToolBar.setCurrentItem(0);
binding.blogTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onTabSelected(TabLayout.Tab tab) {
tab.setText(getImageSpanSelected(tabImages.get(tab.getPosition())));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.setText(getImageSpanUnSelected(tabImages.get(tab.getPosition())));
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
//markdown实时显示
final Markwon markwon = Markwon.builder(this)
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(Color.GREEN)
.codeBackgroundColor(Color.GRAY);
}
})
.build();
final MarkwonEditor editor = MarkwonEditor.create(markwon);
binding.editTextBlogContent.addTextChangedListener(MarkwonEditorTextWatcher.withPreRender(
editor,
Executors.newCachedThreadPool(),
binding.editTextBlogContent
));
}
//点击头部图片时改变图片颜色
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private CharSequence getImageSpanSelected(int imageId) {
Drawable dImage = getResources().getDrawable(imageId);
dImage.setBounds(0, 0, dImage.getIntrinsicWidth()/2, dImage.getIntrinsicHeight()/2);
dImage.setTint(Color.parseColor("#00aae6"));
SpannableString sp = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(dImage, ImageSpan.ALIGN_BOTTOM);
sp.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sp;
} }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private CharSequence getImageSpanUnSelected(int imageId) {
Drawable dImage = getResources().getDrawable(imageId);
dImage.setBounds(0, 0, dImage.getIntrinsicWidth()/2, dImage.getIntrinsicHeight()/2);
dImage.setTint(Color.parseColor("#999999"));
SpannableString sp = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(dImage, ImageSpan.ALIGN_BOTTOM);
sp.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sp;
}
//字符串拼接形成表格
private String createTable () {
//表格的列数
int line;
//表格的行数
int row;
EditText lineEditText = findViewById(R.id.edit_text_form_line);
if (lineEditText.getText().toString().equals("")) {
line = 3;
} else {
line = Integer.parseInt(lineEditText.getText().toString());
}
EditText rowEditText = findViewById(R.id.edit_text_form_row);
if (rowEditText.getText().toString().equals("")) {
row = 3;
} else {
row = Integer.parseInt(lineEditText.getText().toString());
}
//通过循环制表
StringBuilder table = new StringBuilder("\n"+"|");
for (int i = 0 ; i < row ; i++) {
for (int j = 0 ; j < line ; j++) {
if (i == 0) {
table.append("title|");
} else if (i == 1) {
table.append("-|");
} else {
table.append("content|");
}
}
if (i < row-1) {
table.append("\n"+"|");
}
}
return table.toString();
}
//向输入框中添加markdown语法
private void addMarkdownGrammar(String grammar) {
String rawData = binding.editTextBlogContent.getText().toString();
StringBuilder data = new StringBuilder(rawData);
//将Markdown语法加入到data中并显示在页面上
data.append(grammar);
binding.editTextBlogContent.setText(data.toString());
//使页面指针停于data末尾
binding.editTextBlogContent.setSelection(binding.editTextBlogContent.getText().toString().length());
}
public void onClick(View view) {
String tag = (String) view.getTag();
switch (MarkdownButtonEnum.valueOf(tag)) {
case FONT_BOLD :
addMarkdownGrammar("****");
break;
case FONT_ITALIC:
addMarkdownGrammar("**");
break;
case FONT_UNDERLINE:
addMarkdownGrammar("++++");
break;
case FONT_SUPERSCRIPT:
addMarkdownGrammar("^^");
break;
case FONT_SUBSCRIPT:
addMarkdownGrammar("~~");
break;
case FONT_STRIKE_THROUGH:
addMarkdownGrammar("~~~~");
break;
case H1:
addMarkdownGrammar("# ");
break;
case H2:
addMarkdownGrammar("## ");
break;
case H3:
addMarkdownGrammar("### ");
break;
case H4:
addMarkdownGrammar("#### ");
break;
case H5:
addMarkdownGrammar("##### ");
break;
case H6:
addMarkdownGrammar("###### ");
break;
case UNORDERED_LIST:
addMarkdownGrammar("+ ");
break;
case CODE_BLOCK:
addMarkdownGrammar("```\n\n```");
break;
case CROSS_LINE:
addMarkdownGrammar("\n***\n");
break;
case TABLE:
addMarkdownGrammar(createTable());
break;
case ORDERED_LIST:
addMarkdownGrammar("\n1. \n2. \n3.");
default:
Log.d("msg", tag);
}
}
} }
package cn.yunliyunwai.beyondclouds.ui.page; package cn.yunliyunwai.beyondclouds.ui.page;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.fonts.Font;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Spannable; import android.text.Spannable;
...@@ -15,9 +15,6 @@ import android.text.style.ImageSpan; ...@@ -15,9 +15,6 @@ import android.text.style.ImageSpan;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.luck.picture.lib.PictureSelector; import com.luck.picture.lib.PictureSelector;
...@@ -26,15 +23,22 @@ import com.luck.picture.lib.config.PictureMimeType; ...@@ -26,15 +23,22 @@ import com.luck.picture.lib.config.PictureMimeType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executors;
import cn.yunliyunwai.beyondclouds.R; import cn.yunliyunwai.beyondclouds.R;
import cn.yunliyunwai.beyondclouds.databinding.ActivityPublishQuestionBinding; import cn.yunliyunwai.beyondclouds.databinding.ActivityPublishQuestionBinding;
import cn.yunliyunwai.beyondclouds.ui.page.markdown.MarkdownButtonEnum; import cn.yunliyunwai.beyondclouds.ui.page.markdown.MarkdownButtonEnum;
import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.editor.MarkwonEditor;
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
public class PublishQuestionActivity extends AppCompatActivity { public class PublishQuestionActivity extends AppCompatActivity {
private ActivityPublishQuestionBinding binding; private ActivityPublishQuestionBinding binding;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
...@@ -79,8 +83,29 @@ public class PublishQuestionActivity extends AppCompatActivity { ...@@ -79,8 +83,29 @@ public class PublishQuestionActivity extends AppCompatActivity {
} }
}); });
//markdown实时显示
final Markwon markwon = Markwon.builder(this)
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
builder
.codeTextColor(Color.GREEN)
.codeBackgroundColor(Color.GRAY);
}
})
.build();
final MarkwonEditor editor = MarkwonEditor.create(markwon);
binding.editTextQuestionContent.addTextChangedListener(MarkwonEditorTextWatcher.withPreRender(
editor,
Executors.newCachedThreadPool(),
binding.editTextQuestionContent
));
} }
//点击头部图片时改变图片颜色
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private CharSequence getImageSpanSelected(int imageId) { private CharSequence getImageSpanSelected(int imageId) {
Drawable dImage = getResources().getDrawable(imageId); Drawable dImage = getResources().getDrawable(imageId);
...@@ -103,6 +128,45 @@ public class PublishQuestionActivity extends AppCompatActivity { ...@@ -103,6 +128,45 @@ public class PublishQuestionActivity extends AppCompatActivity {
return sp; return sp;
} }
//字符串拼接形成表格
private String createTable () {
//表格的列数
int line;
//表格的行数
int row;
EditText lineEditText = findViewById(R.id.edit_text_form_line);
if (lineEditText.getText().toString().equals("")) {
line = 3;
} else {
line = Integer.parseInt(lineEditText.getText().toString());
}
EditText rowEditText = findViewById(R.id.edit_text_form_row);
if (rowEditText.getText().toString().equals("")) {
row = 3;
} else {
row = Integer.parseInt(lineEditText.getText().toString());
}
//通过循环制表
StringBuilder table = new StringBuilder("\n"+"|");
for (int i = 0 ; i < row ; i++) {
for (int j = 0 ; j < line ; j++) {
if (i == 0) {
table.append("title|");
} else if (i == 1) {
table.append("-|");
} else {
table.append("content|");
}
}
if (i < row-1) {
table.append("\n"+"|");
}
}
return table.toString();
}
public void onClick(View view) { public void onClick(View view) {
String tag = (String) view.getTag(); String tag = (String) view.getTag();
switch (MarkdownButtonEnum.valueOf(tag)) { switch (MarkdownButtonEnum.valueOf(tag)) {
...@@ -162,6 +226,7 @@ public class PublishQuestionActivity extends AppCompatActivity { ...@@ -162,6 +226,7 @@ public class PublishQuestionActivity extends AppCompatActivity {
} }
private void addMarkdownGrammar(String grammar) { private void addMarkdownGrammar(String grammar) {
String rawData = binding.editTextQuestionContent.getText().toString(); String rawData = binding.editTextQuestionContent.getText().toString();
StringBuilder data = new StringBuilder(rawData); StringBuilder data = new StringBuilder(rawData);
...@@ -172,44 +237,10 @@ public class PublishQuestionActivity extends AppCompatActivity { ...@@ -172,44 +237,10 @@ public class PublishQuestionActivity extends AppCompatActivity {
binding.editTextQuestionContent.setSelection(binding.editTextQuestionContent.getText().toString().length()); binding.editTextQuestionContent.setSelection(binding.editTextQuestionContent.getText().toString().length());
} }
//字符串拼接形成表格
private String createTable () {
//表格的列数
int line;
//表格的行数
int row;
EditText lineEditText = findViewById(R.id.edit_text_form_line);
if (lineEditText.getText().toString().equals("")) {
line = 3;
} else {
line = Integer.parseInt(lineEditText.getText().toString());
}
EditText rowEditText = findViewById(R.id.edit_text_form_row);
if (rowEditText.getText().toString().equals("")) {
row = 3;
} else {
row = Integer.parseInt(lineEditText.getText().toString());
}
//通过循环制表
StringBuilder table = new StringBuilder("\n"+"|");
for (int i = 0 ; i < row ; i++) {
for (int j = 0 ; j < line ; j++) {
if (i == 0) {
table.append("title|");
} else if (i == 1) {
table.append("-|");
} else {
table.append("content|");
}
}
if (i < row-1) {
table.append("\n"+"|");
}
}
return table.toString();
}
public void addCover(View view) { public void addCover(View view) {
PictureSelector. create(this) PictureSelector. create(this)
......
...@@ -107,7 +107,7 @@ ...@@ -107,7 +107,7 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<EditText <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="正文" android:text="正文"
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
<ScrollView <ScrollView
android:id="@+id/scrollView2" android:id="@+id/scrollView2"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="300dp" android:layout_height="220dp"
android:fadingEdge="vertical" android:fadingEdge="vertical"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
...@@ -81,7 +81,8 @@ ...@@ -81,7 +81,8 @@
<EditText <EditText
android:layout_width="wrap_content" android:id="@+id/edit_text_blog_content"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="正文" android:text="正文"
android:textColor="@color/colorText" android:textColor="@color/colorText"
...@@ -96,17 +97,21 @@ ...@@ -96,17 +97,21 @@
</ScrollView> </ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.viewpager.widget.ViewPager
android:id="@+id/constraintLayout3" android:id="@+id/blog_tool_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="44dp" android:layout_height="0dp"
android:background="@color/colorToolBackground" android:background="#efefef"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/scrollView2"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent">
app:layout_constraintTop_toBottomOf="@+id/scrollView2">
<com.google.android.material.tabs.TabLayout
android:id="@+id/blog_tab_layout"
android:background="#f5f8fa"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.viewpager.widget.ViewPager>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment