Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Algnhsa | 309 | 10 | 23 | 7 days ago | 4 | January 08, 2022 | 5 | apache-2.0 | Go | |
AWS Lambda Go net/http server adapter | ||||||||||
External Adapters Js | 230 | 16 hours ago | 3 | October 27, 2020 | 48 | mit | TypeScript | |||
Monorepo containing JavaScript implementation of external adapters | ||||||||||
Advancedrecyclerview | 179 | 4 years ago | 2 | apache-2.0 | Kotlin | |||||
An easy, empowering Kotlin library for RecyclerView | ||||||||||
Awsgi | 132 | 7 | 3 years ago | 17 | July 07, 2020 | 12 | mit | Python | ||
A WSGI gateway for the AWS API Gateway/Lambda proxy integration | ||||||||||
Hex Arch Kotlin Spring Boot | 125 | 10 months ago | mit | Kotlin | ||||||
Reference JVM multi module project for a reactive micro service and lambda using a hexagonal architecture, DDD, Kotlin, Spring Boot, Quarkus, Lambda, Gradle. | ||||||||||
Ring Aws Lambda Adapter | 45 | 4 | 4 years ago | 3 | March 01, 2016 | 4 | epl-1.0 | Clojure | ||
A ring adapater for use with AWS Lambda and AWS API Gateway | ||||||||||
Noviewholder | 40 | 6 years ago | 1 | Java | ||||||
No ViewHolder, No Adapter!!! 基于反射实现 DATA 和 VIEW 的绑定,不知 ViewHolder 为何物。 | ||||||||||
Bridges | 23 | 3 years ago | 1 | gpl-3.0 | Go | |||||
Chainlink adaptor framework. Create your own adapters with an easy to use interface. | ||||||||||
Aws Lambda Servlet | 20 | 5 years ago | unlicense | Java | ||||||
AWS Lambda adapter for Java's Servlets (and Jersey in particular, JAX-RS implementation) | ||||||||||
Vertx Aws Lambda | 16 | 5 years ago | 1 | apache-2.0 | Java | |||||
AWS Lambda adapter for Vert.x web applications |
Java
Android
MVVM
RNN
很不幸截止到该次 update 时,raw.github.com 无法正常访问,被墙,README 内预览图无法显示
操作系统
:Windows 10
IDE
:Android Studio 3.14
构建工具
:Gradle 3.4.0
VCS
:Git 2.15.0.windows.1
JDK
:JDK 1.8.0_144
Android SDK
:API 28
tensorflow
:1.11.0
python
:2.7.5
服务端OS
:centos-release-7-4.1708.el7
简札 以诗词为基,以交流为体,赋予诗词更强的烟火气,使之走进普罗大众的手心。让简札的用户切实体会到诗词之美,并从中获得愉悦的精神享受,吸引更多人加入到欣赏、创作诗词的洪流中来。在简札中,用户可以用轻松简单的操作,让诗词绽放出更强的生命力。
创作诗词
可以通过自然语言处理技术和机器学习技术自动生成格律诗、自由诗、藏头诗、藏字诗,藏头诗和藏字诗的生成需要输入种子。输入种子的编辑框位于页面中间的底部。
修改诗词
点击诗词书写框,会弹出弹窗,可以在已有诗的基础上,修改诗词。
保存诗词
保存诗这个功能会将写诗的页面做成海报保存到本地相册
更换背景
在更换背景模块中用户可以在手机相册中自由选择背景图,定制个性化诗词背景。
功能总结
简札 的用户在写诗界面可以自动创作藏头诗、藏字诗、格律诗或自由诗。上方图标有更换背景、保存诗词等功能。
藏头诗、藏字诗功能中可以让用户自主选择种子,借此激起用户的阅读、创作和发布的兴趣。
本软件的目标受众为全年龄段,操作简单,图标清晰,功能明确。无论是为幼儿启蒙还是为诗词行家带去几分乐趣都是我的荣幸。
简札 以诗词为基,以交流为体,致力于赋予诗词更强的烟火气,使之走进普罗大众的手心。让简札的用户切实体会到诗词之美,并从中获得愉悦的精神享受,吸引更多人加入到欣赏、创作诗词的洪流中来。在简札中,用户可以用轻松简单的操作,让诗词绽放出更强的生命力。
本软件的目标受众为全年龄段,无论是为幼儿启蒙还是为诗词行家带去几分乐趣都是我的荣幸,考虑到用户中可能诗词爱好者居多,针对爱好者的普遍审美设计了简洁隽永的浅茶色主题,为用户提供清新的视觉感受。
如果在未来有机会,功能会逐渐完全,可以与个性化自定义写诗、画图、诗人等相关联,开发出更加强大的简札。届时必将吸引更多的用户参与到这款软件中来,则可以建立一个互联分享的圈子,更好更广泛的弘扬传统文化。
PoemDisplayView
,和 activity ,fragment 子包CharacterUtil
为中文检测工具,StatusUtil
为调整 Android 顶部状态栏及适配全面屏工具, HttpUtil
为我封装的使用 Socket 实现的发起 Get 请求的工具WeakReference
不会造成内存泄漏─java
└─com
└─zq
└─poem
│ ext.kt
│
├─application
│ CommonApplication.java
│ CommonContext.java
│
├─model
│ │ MainViewModel.java
│ │ ModelApi.java
│ │ Writer.java
│ │
│ └─user
│ MainModel.kt
│ Status.kt
│ UserApiManager.kt
│ UserInfoApi.kt
│
├─service
│ CoroutineCallAdapter.kt
│ RefreshableLiveData.kt
│ RetrofitFactory.kt
│ RetrofitService.kt
│
├─util
│ CharacterUtil.java
│ CoroutineHandler.kt
│ ExGlideEngine.kt
│ GraphicOverlay.java
│ HttpLoggingInterceptor.java
│ HttpUtil.java
│ PermissionUtils.java
│ PicUtil.kt
│ StatusUtils.java
│ TextGraphic.java
│
└─view
│ MyPageAdapter.java
│ PoemDisplayView.java
│
├─activity
│ HomeActivity.java
│ MainActivity.java
│ PhotoMainActivity.kt
│
├─fragment
│ AcrosticFragment.java
│ FreeFragment.java
│ LazyFragment.java
│ MeaningFragment.java
│ RhymeFragment.java
│
└─item
PhotoItem.kt
MainViewModel
,而 HttpUtil 在该项目中因为异步进行网络请求会出现并发访问的情况,为了线程安全和效率,使用 Double CheckStatusUtils
,由于只会在窗口创建时使用一次,则没有使用单例模式,而是使用完毕及时释放,避免资源占用public class HttpUtil {
/**host of my serve*/
private static final String BASE_URL = "http://sgxm.tech";
/** Singleton design pattern */
private static volatile HttpUtil ourInstance;
/** stream writer */
private BufferedWriter bufferedWriter;
/** stream reader */
private BufferedReader bufferedReader;
/**
* double check thread-safe and efficient
*
* @return the instance of this class
*/
public static HttpUtil getInstance() {
if (ourInstance == null) {
synchronized (HttpUtil.class) {
if (ourInstance == null) {
ourInstance = new HttpUtil();
}
}
}
return ourInstance;
}
private HttpUtil() {}
.
.
.
}
Observable
/**
* Observe design pattern
*
* Livedata is a kind of data with lifecycle
* I use it to save verse request from the serve
* when its value changes, my observer will update UI
* and according with the lifecycle of UI component
*/
private MutableLiveData<List<String>> freeData = new MutableLiveData<>();
private MutableLiveData<List<String>> rhymeData = new MutableLiveData<>();
private MutableLiveData<List<String>> arcrosticData = new MutableLiveData<>();
private MutableLiveData<List<String>> meaningData = new MutableLiveData<>();
/**
* livedata which saves the status of network request,when its value changes to false
* the observer will toast message
*/
private MutableLiveData<Boolean> status = new MutableLiveData<>();
Observer
MainViewModel.getInstance().getFreeData().observe(this, new Observer<List<String>>() {
@Override
public void onChanged(@Nullable List<String> strings) {
poemDisplayView.setVerses(strings);
}
});
. . .
status.observeForever(new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
if (!aBoolean)
Toast.makeText(CommonContext.getCommonContext(), "写得太累了,休息一下", Toast.LENGTH_SHORT).show();
}
});
. . .
Thread
和 Runnable
,代理类和被代理类都实现了相同的接口,而代理类持有被代理对象的引用,静态代理最大的好处就是可以让被代理对象专心去完成它的工作而不需要操心其它Writer
为两者都需实现的接口,ModelApi
为被代理类,其所需要做的事就是专心去连接服务器获取数据,MainViewModel
为代理类Interface
public interface Writer {
void write(final String path, final ModelApi.TYPE type, final String hint, final int times);
}
Proxy
public class MainViewModel implements Writer {
/**
* Static Proxy design pattern
*
* MODELAPI is the real object and MainViewModel is the proxy
* both of them implements the interface Writer
*/
private static final Writer MODELAPI = new ModelApi();
. . .
@Override
public void write(String path, ModelApi.TYPE type, String hint, int times) {
. . .
MODELAPI.write(path, type, hint, times);
. . .
}
}
Real Object
public class ModelApi implements Writer {
. . .
@Override
public void write(final String path, final TYPE type, final String hint, final int times) {
. . .
}
}
Adapter
public class MyPageAdapter extends FragmentPagerAdapter {
/** context will be used*/
private Context context;
/** lists of window */
private List<Fragment> fragmentList;
/** list of window's title*/
private List<String> list_Title;
/**
* main constructor
*
* @param fm manager to manage fragments
* @param context context will be used
* @param fragmentList list of fragment
* @param list_Title list of fragment's title
*/
public MyPageAdapter(FragmentManager fm, Context context, List<Fragment> fragmentList, List<String> list_Title) {
super(fm);
this.context = context;
this.fragmentList = fragmentList;
this.list_Title = list_Title;
}
@Override
public int getCount() {
return fragmentList.size();
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public CharSequence getPageTitle(int position) {
return list_Title.get(position);
}
}
LazyFragment
为顶级抽象类,有四个子类,且均为懒加载模式,在 Android 中, 当某个页面还未被访问时,就不去加载它,可以很大程度上提到 APP 的启动速度 ├─LazyFragment
│—— FreeFragment
│—— AcrosticFragment
│—— RhymeFragment
│—— MeaningFragment
LazyFragment
public abstract class LazyFragment extends Fragment {
. . .
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (mRootView != null) {
isViewCreated = true;
return mRootView;
}
Context context = inflater.getContext();
FrameLayout root = new FrameLayout(context);
mViewStub = new ViewStubCompat(context, null);
mViewStub.setLayoutResource(getResId());
root.addView(mViewStub, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
root.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT));
mRootView = root;
if (isUserVisible) {
realLoad();
}
isViewCreated = true;
return mRootView;
}
. . .
}
PoemDisplayView
完全根据数据自行计算绘制,为盒子模型, 并实现了逐字显示动画效果Diagram
public class PoemDisplayView extends View {
/**
* padding padding
* Left col Right
* | | Spacing | | | | |
* +---+---------+---------+---------+---------+---+
* | | | | padding Top
* +---+---------------------------------------+---+ ---
* | | colWidth | |
* | | _ | |
* | | |x| col x x x | |
* | | |x| Height x x x | | Content Height
* | | |x| x x x | |
* | | |x| x x x | |
* | | |x| x x x | |
* | | - | |
* +---+---------------------------------------+---+ ---
* | | | | padding Bottom
* +---+---------+---------+---------+---------+---+
* | ContentWidth |
*/
. . .
}
Draw
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
cols = verses.size();
if (cols > 0) {
singleVerseLength = verses.get(0).length();
contentWidth = getWidth() - paddingLeft - paddingRight;
contentHeight = getHeight() - paddingTop - paddingBottom;
colSpacing = (contentWidth - cols * mVersePaint.getTextSize()) / (cols - 1);
colWidth = mVersePaint.getTextSize();
colHeight = (singleVerseLength + 2) * mVersePaint.getTextSize();
srcBitmap = Bitmap.createBitmap(contentWidth, (int) colHeight, Bitmap.Config.ARGB_8888);
srcCanvas = new Canvas(srcBitmap);
shaderBitmap = Bitmap.createBitmap(contentWidth, (int) colHeight, Bitmap.Config.ARGB_8888);
shaderCanvas = new Canvas(shaderBitmap);
//draw verse
for (int i = 0; i < cols; ++i) {
srcCanvas.save();
srcCanvas.translate(i * (colSpacing + colWidth), 0);
StaticLayout staticLayout = new StaticLayout(verses.get(i), mVersePaint, (int) mVersePaint.getTextSize(), Layout.Alignment.ALIGN_CENTER, 1, 0, true);
staticLayout.draw(srcCanvas);
srcCanvas.restore();
}
//draw dst(shader) bitmap
//draw transparent
mShadowPaint.setColor(Color.TRANSPARENT);
RectF rectF = new RectF(0, 0, contentWidth, colHeight);
shaderCanvas.drawRect(rectF, mShadowPaint);
//draw black
mShadowPaint.setColor(Color.BLACK);
int drawCols = (int) Math.ceil(postIndex / colHeight);
for (int i = 0; i < drawCols; ++i) {
shaderCanvas.save();
shaderCanvas.translate(i * (colSpacing + colWidth), 0);
rectF = new RectF(0, 0, colWidth, postIndex - i * colHeight);
shaderCanvas.drawRect(rectF, mShadowPaint);
shaderCanvas.restore();
}
//combine
beforeDraw();
mShadowPaint.setXfermode(xformode);
srcCanvas.drawBitmap(shaderBitmap, 0, 0, mShadowPaint);
mShadowPaint.setXfermode(null);
//draw final bitmap
int top;
if (colHeight >= contentHeight)
top = 0;
else
top = (getHeight() - (int) colHeight) / 2;
canvas.drawBitmap(srcBitmap, paddingLeft, top, null);
if (postIndex < cols * colHeight) {
postIndex += 5;
postInvalidateDelayed(4);
} else {
postIndex = 0;
}
}
}
后期也会改为使用第三方网络框架,更稳定且更便捷,这次只是想试一下,该模块高度解耦,可以做到无感知替换
服务器域名为 sgxm.tech
端口号为 5000
, api 为/poem
,支持的参数有style
start
,服务器也为自己搭建,同时自己的博客也在上面
将 BaseUrl 定义为常量,对 api 和 Query 参数进行拼接,组成完成的 URL,使用流操作发送读取数据
/**
* Socket coding
*
* Use socket to connect my serve and send http get request
* then send data back to my model
*
* @param path request api
* @param port which port will be request
* @param query query params of get request
* @return return the response of request which has been clipped
*/
public String httpGet(String path, int port, Map<String, String> query) {
StringBuilder url = new StringBuilder(BASE_URL + ":" + String.valueOf(port) + path);
if (!query.isEmpty()) {
url.append("?");
for (Map.Entry<String, String> entry : query.entrySet()) {
url.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
url.deleteCharAt(url.length() - 1);
}
StringBuilder res = new StringBuilder();
try {
SocketAddress dest = new InetSocketAddress(new URL(url.toString()).getHost(), port);
Socket socket = new Socket();
socket.connect(dest);
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("GET " + url + " HTTP/1.0\r\n");
bufferedWriter.write("Host:" + BASE_URL + "\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.flush();
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream, "utf-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
res.append(line);
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return res.substring(res.indexOf("GMT") + 3);
}
Tab
的字体,Indicator
的颜色和长度,反射中涉及数组,内部类等,需要多次反射才能访问到我想要的属性 /**
* Reflect
*
* I use reflect to modify some property of the UI components
* which didn't provide api to modify it, such as typeface
*/
private void reflectTypeface() {
ArrayList<TabLayout.Tab> tabs;
Class tabLayoutClazz = tabLayout.getClass();
try {
Field tabsField = tabLayoutClazz.getDeclaredField("mTabs");
tabsField.setAccessible(true);
tabs = (ArrayList<TabLayout.Tab>) tabsField.get(tabLayout);
for (TabLayout.Tab tab : tabs) {
Class tabClass = tab.getClass();
Field tabViewField = tabClass.getDeclaredField("mView");
tabViewField.setAccessible(true);
View tabView = (View) tabViewField.get(tab);
Class tabViewClazz = tabView.getClass();
Field textViewField = tabViewClazz.getDeclaredField("mTextView");
textViewField.setAccessible(true);
TextView cusTextView = (TextView) textViewField.get(tabView);
cusTextView.setTypeface(Typeface.createFromAsset(getAssets(), "FZCSJW.TTF"));
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* Reflect
*
* @see #reflectTypeface()
* modify TabLayout Strip color and length
*/
private void reflectLengthColor() {
Class<?> tabLayoutClazz = tabLayout.getClass();
Field tabStrip = null;
try {
tabStrip = tabLayoutClazz.getDeclaredField("mTabStrip");
tabStrip.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
LinearLayout llTab = null;
try {
llTab = (LinearLayout) tabStrip.get(tabLayout);
Method method = llTab.getClass().getDeclaredMethod("setSelectedIndicatorColor", int.class);
method.setAccessible(true);
method.invoke(llTab, getResources().getColor(R.color.colorLine));
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, Resources.getSystem().getDisplayMetrics());
int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, Resources.getSystem().getDisplayMetrics());
for (int i = 0; i < (llTab != null ? llTab.getChildCount() : 0); i++) {
View child = llTab.getChildAt(i);
child.setPadding(0, 0, 0, 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
params.leftMargin = left;
params.rightMargin = right;
child.setLayoutParams(params);
child.invalidate();
}
}
tv_enter.setOnClickListener((v)->{
Intent intent = new Intent(MainActivity.this, HomeActivity.class);
startActivity(intent);
finish();
});
. . .
MainViewModel.getInstance().getArcrosticData().observe(this, (string) -> {
poemDisplayView.setVerses(strings);
});
RNN 模型基于贝叶斯公式来进行训练
数据集为全唐诗,首先将所有词语进行one-hot编码,输入只有一个隐藏层的神经网络,定义好loss后进行训练
代价函数为交叉熵,在语言模型中,模型是通过训练集得到的,交叉熵就是衡量这个模型在测试集上的正确率
这个模型只占改项目的很小一部分,当初也是当作玩具来训练的,训练出来的模型不具有很强的文化底蕴,但代码中对于数据模块充分解耦,任何人都已将自己的模型以任何形式的数据源插入到改项目中
Script is licensed under MIT license with one exception:
Do not create a public WordPress plugin based on it, as I will develop it.
If you need to use it for a public WordPress plugin right now, please ask me by email first. Thanks!
Attribution is not required, but much appreciated, especially if you’re making a product for developers.