アプリ設定に簡略表示を追加

This commit is contained in:
tateisu 2017-04-29 18:12:20 +09:00
parent 671a1e70b2
commit 2d7e82163d
19 changed files with 955 additions and 113 deletions

View File

@ -9,8 +9,8 @@ android {
applicationId "jp.juggler.subwaytooter"
minSdkVersion 21
targetSdkVersion 25
versionCode 20
versionName "0.2.0"
versionCode 21
versionName "0.2.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

View File

@ -35,6 +35,7 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O
Switch swDontConfirmBeforeCloseColumn;
Switch swPriorLocalURL;
Switch swDisableFastScroller;
Switch swSimpleList;
Spinner spBackButtonAction;
Spinner spUITheme;
@ -57,7 +58,8 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O
swDisableFastScroller = (Switch) findViewById( R.id.swDisableFastScroller );
swDisableFastScroller.setOnCheckedChangeListener( this );
swSimpleList = (Switch) findViewById( R.id.swSimpleList );
swSimpleList.setOnCheckedChangeListener( this );
{
String[] caption_list = new String[ 4 ];
@ -92,6 +94,8 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O
swDontConfirmBeforeCloseColumn.setChecked( pref.getBoolean( Pref.KEY_DONT_CONFIRM_BEFORE_CLOSE_COLUMN, false ) );
swPriorLocalURL.setChecked( pref.getBoolean( Pref.KEY_PRIOR_LOCAL_URL, false ) );
swDisableFastScroller.setChecked( pref.getBoolean( Pref.KEY_DISABLE_FAST_SCROLLER, false ) );
swSimpleList.setChecked( pref.getBoolean(Pref.KEY_SIMPLE_LIST,false) );
spBackButtonAction.setSelection( pref.getInt(Pref.KEY_BACK_BUTTON_ACTION,0) );
spUITheme.setSelection( pref.getInt(Pref.KEY_UI_THEME,0) );
load_busy = false;
@ -103,6 +107,7 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O
.putBoolean( Pref.KEY_DONT_CONFIRM_BEFORE_CLOSE_COLUMN, swDontConfirmBeforeCloseColumn.isChecked() )
.putBoolean( Pref.KEY_PRIOR_LOCAL_URL, swPriorLocalURL.isChecked() )
.putBoolean( Pref.KEY_DISABLE_FAST_SCROLLER, swDisableFastScroller.isChecked() )
.putBoolean( Pref.KEY_SIMPLE_LIST, swSimpleList.isChecked() )
.putInt( Pref.KEY_BACK_BUTTON_ACTION, spBackButtonAction.getSelectedItemPosition() )
.putInt( Pref.KEY_UI_THEME, spUITheme.getSelectedItemPosition() )
.apply();

View File

@ -1,17 +1,28 @@
package jp.juggler.subwaytooter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.widget.AutoScrollHelper;
import android.support.v4.widget.PopupWindowCompat;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
@ -19,7 +30,9 @@ import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.android.volley.toolbox.NetworkImageView;
@ -42,6 +55,9 @@ import jp.juggler.subwaytooter.table.MediaShown;
import jp.juggler.subwaytooter.table.SavedAccount;
import jp.juggler.subwaytooter.util.Emojione;
import jp.juggler.subwaytooter.util.LogCategory;
import jp.juggler.subwaytooter.util.MyLinkMovementMethod;
import jp.juggler.subwaytooter.util.MyListView;
import jp.juggler.subwaytooter.util.MyTextView;
import jp.juggler.subwaytooter.util.Utils;
class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, SwipyRefreshLayout.OnRefreshListener, CompoundButton.OnCheckedChangeListener {
@ -51,10 +67,12 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
final AtomicBoolean is_destroyed = new AtomicBoolean( false );
private final Column column;
final SavedAccount access_info;
ColumnViewHolder( ActMain activity, Column column ){
this.activity = activity;
this.column = column;
this.access_info = column.access_info;
}
private boolean isPageDestroyed(){
@ -68,7 +86,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
}
private TextView tvLoading;
private ListView listView;
private MyListView listView;
private TextView tvColumnContext;
private TextView tvColumnName;
private StatusListAdapter status_adapter;
@ -80,10 +98,13 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
private View llColumnSetting;
private EditText etRegexFilter;
private TextView tvRegexFilterError;
private boolean bSimpleList;
void onPageCreate( View root, int page_idx, int page_count ){
log.d( "onPageCreate:%s", column.getColumnName( true ) );
( (TextView) root.findViewById( R.id.tvColumnIndex ) )
.setText( activity.getString( R.string.column_index, page_idx + 1, page_count ) );
@ -95,7 +116,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
root.findViewById( R.id.llColumnHeader ).setOnClickListener( this );
tvLoading = (TextView) root.findViewById( R.id.tvLoading );
listView = (ListView) root.findViewById( R.id.listView );
listView = (MyListView) root.findViewById( R.id.listView );
status_adapter = new StatusListAdapter();
listView.setAdapter( status_adapter );
@ -230,6 +251,14 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
swipyRefreshLayout.setEnabled( false );
}
bSimpleList = activity.pref.getBoolean(Pref.KEY_SIMPLE_LIST,false);
if( column.type == Column.TYPE_CONVERSATION ){
bSimpleList = false;
}
if(bSimpleList){
listView.setOnItemClickListener( status_adapter );
}
//
column.addVisualListener( this );
@ -487,7 +516,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
btnStatusCount.setOnClickListener( this );
btnMore.setOnClickListener( this );
tvNote.setMovementMethod( LinkMovementMethod.getInstance() );
tvNote.setMovementMethod( MyLinkMovementMethod.getInstance() );
}
void bind( ActMain activity, SavedAccount access_info, TootAccount who ){
@ -556,7 +585,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
}
}
private class StatusListAdapter extends BaseAdapter {
private class StatusListAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {
final ArrayList< Object > status_list = new ArrayList<>();
< T > void set( List< T > src ){
@ -587,15 +616,23 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
StatusViewHolder holder;
if( view == null ){
view = activity.getLayoutInflater().inflate( R.layout.lv_status, parent, false );
view = activity.getLayoutInflater().inflate( bSimpleList ? R.layout.lv_status_simple : R.layout.lv_status, parent, false );
holder = new StatusViewHolder( view );
view.setTag( holder );
}else{
holder = (StatusViewHolder) view.getTag();
}
holder.bind( activity, o, column.access_info );
holder.bind( o );
return view;
}
@Override
public void onItemClick( AdapterView< ? > parent, View view, int position, long id ){
Object tag = view.getTag();
if( tag instanceof StatusViewHolder){
((StatusViewHolder)tag).onItemClick(view);
}
}
}
private class StatusViewHolder implements View.OnClickListener {
@ -619,12 +656,12 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
final TextView tvAcct;
final View llContentWarning;
final TextView tvContentWarning;
final MyTextView tvContentWarning;
final Button btnContentWarning;
final View llContents;
final TextView tvMentions;
final TextView tvContent;
final MyTextView tvMentions;
final MyTextView tvContent;
final View flMedia;
final View btnHideMedia;
@ -635,22 +672,17 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
final NetworkImageView ivMedia3;
final NetworkImageView ivMedia4;
final ImageButton btnReply;
final Button btnBoost;
final Button btnFavourite;
final ImageButton btnMore;
final ButtonsForStatus buttons_for_status;
final View llSearchTag;
final Button btnSearchTag;
TootStatus status;
SavedAccount access_info;
TootAccount account_thumbnail;
TootAccount account_boost;
TootAccount account_follow;
View btnConversation;
String search_tag;
View llSearchTag;
Button btnSearchTag;
TootGap gap;
StatusViewHolder( View view ){
@ -675,18 +707,14 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
this.tvAcct = (TextView) view.findViewById( R.id.tvAcct );
this.llContentWarning = view.findViewById( R.id.llContentWarning );
this.tvContentWarning = (TextView) view.findViewById( R.id.tvContentWarning );
this.tvContentWarning = (MyTextView) view.findViewById( R.id.tvContentWarning );
this.btnContentWarning = (Button) view.findViewById( R.id.btnContentWarning );
this.llContents = view.findViewById( R.id.llContents );
this.tvContent = (TextView) view.findViewById( R.id.tvContent );
this.tvMentions = (TextView) view.findViewById( R.id.tvMentions );
this.tvContent = (MyTextView) view.findViewById( R.id.tvContent );
this.tvMentions = (MyTextView) view.findViewById( R.id.tvMentions );
this.btnConversation = view.findViewById( R.id.btnConversation );
this.btnReply = (ImageButton) view.findViewById( R.id.btnReply );
this.btnBoost = (Button) view.findViewById( R.id.btnBoost );
this.btnFavourite = (Button) view.findViewById( R.id.btnFavourite );
this.btnMore = (ImageButton) view.findViewById( R.id.btnMore );
this.buttons_for_status = bSimpleList ? null : new ButtonsForStatus( view );
this.flMedia = view.findViewById( R.id.flMedia );
this.btnHideMedia = view.findViewById( R.id.btnHideMedia );
@ -708,11 +736,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
ivMedia3.setOnClickListener( this );
ivMedia4.setOnClickListener( this );
btnFollow.setOnClickListener( this );
btnConversation.setOnClickListener( this );
btnReply.setOnClickListener( this );
btnBoost.setOnClickListener( this );
btnFavourite.setOnClickListener( this );
btnMore.setOnClickListener( this );
ivThumbnail.setOnClickListener( this );
// ここを個別タップにすると邪魔すぎる tvName.setOnClickListener( this );
@ -720,12 +744,19 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
llFollow.setOnClickListener( this );
btnFollow.setOnClickListener( this );
tvContent.setMovementMethod( LinkMovementMethod.getInstance() );
tvMentions.setMovementMethod( LinkMovementMethod.getInstance() );
tvContent.setMovementMethod( MyLinkMovementMethod.getInstance() );
tvMentions.setMovementMethod( MyLinkMovementMethod.getInstance() );
tvContentWarning.setMovementMethod( MyLinkMovementMethod.getInstance() );
}
void bind( ActMain activity, Object item, SavedAccount access_info ){
this.access_info = access_info;
void bind( Object item ){
this.status = null;
this.account_thumbnail = null;
this.account_boost = null;
this.account_follow = null;
this.search_tag = null;
this.gap = null;
llBoosted.setVisibility( View.GONE );
llFollow.setVisibility( View.GONE );
@ -747,7 +778,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
, R.attr.btn_favourite
, Utils.formatSpannable1( activity, R.string.display_name_favourited_by, n.account.display_name )
);
if( n.status != null ) showStatus( activity, n.status, access_info );
if( n.status != null ) showStatus( activity, n.status );
}else if( TootNotification.TYPE_REBLOG.equals( n.type ) ){
showBoost(
n.account
@ -755,7 +786,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
, R.attr.btn_boost
, Utils.formatSpannable1( activity, R.string.display_name_boosted_by, n.account.display_name )
);
if( n.status != null ) showStatus( activity, n.status, access_info );
if( n.status != null ) showStatus( activity, n.status );
}else if( TootNotification.TYPE_FOLLOW.equals( n.type ) ){
showBoost(
n.account
@ -764,17 +795,17 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
, Utils.formatSpannable1( activity, R.string.display_name_followed_by, n.account.display_name )
);
//
showFollow(
n.account
);
showFollow( n.account );
}else if( TootNotification.TYPE_MENTION.equals( n.type ) ){
showBoost(
n.account
, n.time_created_at
, R.attr.btn_reply
, Utils.formatSpannable1( activity, R.string.display_name_replied_by, n.account.display_name )
);
if( n.status != null ) showStatus( activity, n.status, access_info );
if(!bSimpleList){
showBoost(
n.account
, n.time_created_at
, R.attr.btn_reply
, Utils.formatSpannable1( activity, R.string.display_name_replied_by, n.account.display_name )
);
}
if( n.status != null ) showStatus( activity, n.status );
}
}else if( item instanceof TootStatus ){
TootStatus status = (TootStatus) item;
@ -785,9 +816,9 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
, R.attr.btn_boost
, Utils.formatSpannable1( activity, R.string.display_name_boosted_by, status.account.display_name )
);
showStatus( activity, status.reblog, access_info );
showStatus( activity, status.reblog );
}else{
showStatus( activity, status, access_info );
showStatus( activity, status );
}
}else if( item instanceof TootGap ){
showGap( (TootGap) item );
@ -827,12 +858,12 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
btnFollow.setImageResource( Styler.getAttributeResourceId( activity, R.attr.ic_account_add ) );
}
private void showStatus( ActMain activity, TootStatus status, SavedAccount account ){
private void showStatus( ActMain activity, TootStatus status ){
this.status = status;
account_thumbnail = status.account;
llStatus.setVisibility( View.VISIBLE );
tvAcct.setText( account.getFullAcct( status.account ) );
tvAcct.setText( access_info.getFullAcct( status.account ) );
tvTime.setText( TootStatus.formatTime( status.time_created_at ) );
tvName.setText( status.account.display_name );
@ -860,7 +891,7 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
}else{
llContentWarning.setVisibility( View.VISIBLE );
tvContentWarning.setText( status.decoded_spoiler_text );
boolean cw_shown = ContentWarning.isShown( account.host, status.id, false );
boolean cw_shown = ContentWarning.isShown( access_info.host, status.id, false );
showContent( cw_shown );
}
@ -874,41 +905,16 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
setMedia( ivMedia4, status, 3 );
// hide sensitive media
boolean is_shown = MediaShown.isShown( account.host, status.id, account.dont_hide_nsfw || ! status.sensitive );
boolean is_shown = MediaShown.isShown( access_info.host, status.id, access_info.dont_hide_nsfw || ! status.sensitive );
btnShowMedia.setVisibility( ! is_shown ? View.VISIBLE : View.GONE );
}
int color_normal = Styler.getAttributeColor( activity, R.attr.colorImageButton );
int color_accent = Styler.getAttributeColor( activity, R.attr.colorImageButtonAccent );
if( TootStatus.VISIBILITY_DIRECT.equals( status.visibility ) ){
setButton( btnBoost, false, color_accent, R.attr.ic_mail, "" );
}else if( TootStatus.VISIBILITY_PRIVATE.equals( status.visibility ) ){
setButton( btnBoost, false, color_accent, R.attr.ic_lock, "" );
}else if( activity.isBusyBoost( account, status ) ){
setButton( btnBoost, false, color_normal, R.attr.btn_refresh, "?" );
}else{
int color = ( status.reblogged ? color_accent : color_normal );
setButton( btnBoost, true, color, R.attr.btn_boost, Long.toString( status.reblogs_count ) );
if( buttons_for_status != null){
buttons_for_status.bind( status );
}
if( activity.isBusyFav( account, status ) ){
setButton( btnFavourite, false, color_normal, R.attr.btn_refresh, "?" );
}else{
int color = ( status.favourited ? color_accent : color_normal );
setButton( btnFavourite, true, color, R.attr.btn_favourite, Long.toString( status.favourites_count ) );
}
}
private void setButton( Button b, boolean enabled, int color, int icon_attr, String text ){
Drawable d = Styler.getAttributeDrawable( activity, icon_attr ).mutate();
d.setColorFilter( color, PorterDuff.Mode.SRC_ATOP );
b.setCompoundDrawablesRelativeWithIntrinsicBounds( d, null, null, null );
b.setText( text );
b.setTextColor( color );
b.setEnabled( enabled );
}
private void showContent( boolean shown ){
btnContentWarning.setText( shown ? R.string.hide : R.string.show );
@ -958,21 +964,6 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
break;
}
case R.id.btnConversation:
activity.performConversation( access_info, status );
break;
case R.id.btnReply:
activity.performReply( access_info, status );
break;
case R.id.btnBoost:
activity.performBoost( access_info, status, false );
break;
case R.id.btnFavourite:
activity.performFavourite( access_info, status );
break;
case R.id.btnMore:
activity.openStatusMoreMenu( access_info, status );
break;
case R.id.ivThumbnail:
activity.performOpenUser( access_info, account_thumbnail );
break;
@ -1023,6 +1014,166 @@ class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, S
}
}
// 簡略ビューの時だけ呼ばれる
void onItemClick(View anchor){
if( status != null ){
// ポップアップを表示する
ListItemPopup popup = new ListItemPopup();
popup.show( anchor, status );
}
}
}
private class ButtonsForStatus implements View.OnClickListener {
final ImageButton btnConversation;
final ImageButton btnReply;
final Button btnBoost;
final Button btnFavourite;
final ImageButton btnMore;
ButtonsForStatus(View viewRoot){
btnConversation = (ImageButton) viewRoot.findViewById( R.id.btnConversation );
btnReply = (ImageButton) viewRoot.findViewById( R.id.btnReply );
btnBoost = (Button) viewRoot.findViewById( R.id.btnBoost );
btnFavourite = (Button) viewRoot.findViewById( R.id.btnFavourite );
btnMore = (ImageButton) viewRoot.findViewById( R.id.btnMore );
btnConversation.setOnClickListener( this );
btnReply.setOnClickListener( this );
btnBoost.setOnClickListener( this );
btnFavourite.setOnClickListener( this );
btnMore.setOnClickListener( this );
}
TootStatus status;
void bind( TootStatus status ){
this.status = status;
int color_normal = Styler.getAttributeColor( activity, R.attr.colorImageButton );
int color_accent = Styler.getAttributeColor( activity, R.attr.colorImageButtonAccent );
if( TootStatus.VISIBILITY_DIRECT.equals( status.visibility ) ){
setButton( btnBoost, false, color_accent, R.attr.ic_mail, "" );
}else if( TootStatus.VISIBILITY_PRIVATE.equals( status.visibility ) ){
setButton( btnBoost, false, color_accent, R.attr.ic_lock, "" );
}else if( activity.isBusyBoost( access_info, status ) ){
setButton( btnBoost, false, color_normal, R.attr.btn_refresh, "?" );
}else{
int color = ( status.reblogged ? color_accent : color_normal );
setButton( btnBoost, true, color, R.attr.btn_boost, Long.toString( status.reblogs_count ) );
}
if( activity.isBusyFav( access_info, status ) ){
setButton( btnFavourite, false, color_normal, R.attr.btn_refresh, "?" );
}else{
int color = ( status.favourited ? color_accent : color_normal );
setButton( btnFavourite, true, color, R.attr.btn_favourite, Long.toString( status.favourites_count ) );
}
}
private void setButton( Button b, boolean enabled, int color, int icon_attr, String text ){
Drawable d = Styler.getAttributeDrawable( activity, icon_attr ).mutate();
d.setColorFilter( color, PorterDuff.Mode.SRC_ATOP );
b.setCompoundDrawablesRelativeWithIntrinsicBounds( d, null, null, null );
b.setText( text );
b.setTextColor( color );
b.setEnabled( enabled );
}
PopupWindow close_window;
@Override public void onClick( View v ){
if( close_window != null ) close_window.dismiss();
switch(v.getId()){
case R.id.btnConversation:
activity.performConversation( access_info, status );
break;
case R.id.btnReply:
activity.performReply( access_info, status );
break;
case R.id.btnBoost:
activity.performBoost( access_info, status, false );
break;
case R.id.btnFavourite:
activity.performFavourite( access_info, status );
break;
case R.id.btnMore:
activity.openStatusMoreMenu( access_info, status );
break;
}
}
}
private class ListItemPopup{
final View viewRoot;
final ButtonsForStatus buttons_for_status;
ListItemPopup( ){
viewRoot = activity.getLayoutInflater().inflate( R.layout.list_item_popup, null, false );
buttons_for_status = new ButtonsForStatus( viewRoot );
}
PopupWindow window;
void show(View anchor, TootStatus status ){
//
window = new PopupWindow(activity);
window.setWidth( WindowManager.LayoutParams.WRAP_CONTENT );
window.setHeight( WindowManager.LayoutParams.WRAP_CONTENT );
window.setContentView( viewRoot );
window.setBackgroundDrawable( new ColorDrawable(0x00000000) );
window.setTouchable(true);
window.setOutsideTouchable( true );
window.setTouchInterceptor( new View.OnTouchListener(){
@Override public boolean onTouch( View v, MotionEvent event ){
if( MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_OUTSIDE){
window.dismiss();
listView.last_popup_close = SystemClock.elapsedRealtime();
return true;
}
return false;
}
} );
buttons_for_status.bind( status );
buttons_for_status.close_window = window;
int[] location = new int[2];
anchor.getLocationOnScreen(location);
int anchor_top = location[1];
listView.getLocationOnScreen(location);
int listView_top = location[1];
int clip_top = listView_top + (int)(0.5f + 8f * activity.density );
int clip_bottom = listView_top + listView.getHeight() - (int)(0.5f + 8f * activity.density );
int popup_height = (int)(0.5f + (56f+24f) * activity.density );
int popup_y = anchor_top + anchor.getHeight()/2;
if(popup_y < clip_top){
// 画面外のは画面内にする
popup_y = clip_top;
}else if( clip_bottom - popup_y < popup_height ){
// 画面外のは画面内にする
if( popup_y > clip_bottom ) popup_y = clip_bottom;
// 画面の下側にあるならポップアップの吹き出しが下から出ているように見せる
viewRoot.findViewById( R.id.ivTriangleTop ).setVisibility( View.GONE );
viewRoot.findViewById( R.id.ivTriangleBottom ).setVisibility( View.VISIBLE );
popup_y -= popup_height;
}
window.showAtLocation(
listView
, Gravity.CENTER_HORIZONTAL|Gravity.TOP
, 0
, popup_y
);
}
}
}

View File

@ -4,18 +4,20 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class Pref {
class Pref {
public static SharedPreferences pref( Context context){
static SharedPreferences pref( Context context ){
return PreferenceManager.getDefaultSharedPreferences( context );
}
private static final String KEY_BACK_TO_COLUMN_LIST ="BackToColumnList"; // 使わなくなった
public static final String KEY_DONT_CONFIRM_BEFORE_CLOSE_COLUMN ="DontConfirmBeforeCloseColumn";
public static final String KEY_BACK_BUTTON_ACTION ="back_button_action";
public static final String KEY_PRIOR_LOCAL_URL = "prior_local_url";
public static final String KEY_DISABLE_FAST_SCROLLER = "disable_fast_scroller";
public static final String KEY_UI_THEME = "ui_theme";
static final String KEY_DONT_CONFIRM_BEFORE_CLOSE_COLUMN ="DontConfirmBeforeCloseColumn";
static final String KEY_BACK_BUTTON_ACTION ="back_button_action";
static final String KEY_PRIOR_LOCAL_URL = "prior_local_url";
static final String KEY_DISABLE_FAST_SCROLLER = "disable_fast_scroller";
static final String KEY_UI_THEME = "ui_theme";
static final String KEY_SIMPLE_LIST = "simple_list";
}

View File

@ -0,0 +1,65 @@
package jp.juggler.subwaytooter.util;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.Touch;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;
public class MyLinkMovementMethod extends LinkMovementMethod {
static MyLinkMovementMethod sInstance;
public static MyLinkMovementMethod getInstance(){
if( sInstance == null )
sInstance = new MyLinkMovementMethod();
return sInstance;
}
@Override
public boolean onTouchEvent( TextView widget, Spannable buffer, MotionEvent event ){
int action = event.getAction();
if( action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN ){
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical( y );
int offset = layout.getOffsetForHorizontal( line, x );
ClickableSpan[] link = buffer.getSpans( offset, offset, ClickableSpan.class );
if( link == null || link.length == 0 ){
Selection.removeSelection( buffer );
Touch.onTouchEvent( widget, buffer, event );
return false;
}
if( action == MotionEvent.ACTION_UP ){
link[ 0 ].onClick( widget );
}else{
// ACTION_DOWN
Selection.setSelection(
buffer
,buffer.getSpanStart( link[ 0 ] )
,buffer.getSpanEnd( link[ 0 ] )
);
}
if (widget instanceof MyTextView){
((MyTextView) widget).linkHit = true;
}
return true;
}
return Touch.onTouchEvent( widget, buffer, event );
}
}

View File

@ -0,0 +1,60 @@
package jp.juggler.subwaytooter.util;
import android.content.Context;
import android.os.SystemClock;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ListView;
public class MyListView extends ListView {
public MyListView( Context context ){
super( context );
}
public MyListView( Context context, AttributeSet attrs ){
super( context, attrs );
}
public MyListView( Context context, AttributeSet attrs, int defStyleAttr ){
super( context, attrs, defStyleAttr );
}
public MyListView( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes ){
super( context, attrs, defStyleAttr, defStyleRes );
}
public long last_popup_close = 0L;
static final String TAG="SubwayTooter";
// @Override public boolean onInterceptTouchEvent( MotionEvent ev ){
// boolean rv = super.onInterceptTouchEvent( ev );
// long now = SystemClock.elapsedRealtime();
// if( now - last_popup_close < 100L ){
// Log.d(TAG,"MyListView onInterceptTouchEvent action="
// + MotionEventCompat.getActionMasked( ev )
// +" rv="+rv
// );
// }
// return rv;
// }
//
@Override public boolean onTouchEvent( MotionEvent ev ){
long now = SystemClock.elapsedRealtime();
if( now - last_popup_close < 30L ){
int action = MotionEventCompat.getActionMasked( ev );
if( action == MotionEvent.ACTION_DOWN ){
return false;
}
boolean rv = super.onTouchEvent( ev );
Log.d(TAG,"MyListView onTouchEvent action=" + action +" rv="+rv );
return rv;
}
return super.onTouchEvent( ev );
}
}

View File

@ -0,0 +1,38 @@
package jp.juggler.subwaytooter.util;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.TextView;
/**
* Created by tateisu on 2017/04/29.
*/
public class MyTextView extends TextView {
public MyTextView( Context context ){
super( context );
}
public MyTextView( Context context, @Nullable AttributeSet attrs ){
super( context, attrs );
}
public MyTextView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ){
super( context, attrs, defStyleAttr );
}
public MyTextView( Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes ){
super( context, attrs, defStyleAttr, defStyleRes );
}
boolean linkHit;
@Override public boolean onTouchEvent(MotionEvent event) {
linkHit = false;
super.onTouchEvent(event);
return linkHit;
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid android:color="?attr/color_column_header"/>
<corners android:radius="16dp" />
<padding android:top="8dp"
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
/>
</shape>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="32.0"
>
<group android:name="group1">
<path
android:name="triangle"
android:fillColor="?attr/color_column_header"
android:pathData="M0,32L16,0L32,24H0z"
/>
</group>
</vector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="32.0"
>
<group android:name="group1">
<path
android:name="triangle"
android:fillColor="?attr/color_column_header"
android:pathData="M0,0L16,24L32,0H0z"
/>
</group>
</vector>

View File

@ -105,6 +105,23 @@ android:scrollbarStyle="outsideOverlay"
<View style="@style/setting_divider"/>
<TextView
style="@style/setting_row_label"
android:text="@string/simple_list"
/>
<LinearLayout style="@style/setting_row_form">
<Switch
android:id="@+id/swSimpleList"
style="@style/setting_horizontal_stretch"
android:gravity="center"
/>
</LinearLayout>
<View style="@style/setting_divider"/>
<!--<TextView-->
<!--style="@style/setting_row_label"-->
<!--android:text="@string/actions"-->

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/list_item_popup_triangle"
android:layout_gravity="center_horizontal"
android:id="@+id/ivTriangleTop"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="56dp"
android:background="@drawable/list_item_popup_bg"
android:orientation="horizontal"
>
<ImageButton
android:id="@+id/btnConversation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/conversation_view"
android:minWidth="40dp"
android:src="?attr/ic_conversation"
/>
<ImageButton
android:id="@+id/btnReply"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="2dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/reply"
android:minWidth="40dp"
android:src="?attr/btn_reply"
/>
<Button
android:id="@+id/btnBoost"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="2dp"
android:background="@drawable/btn_bg_transparent"
android:drawablePadding="4dp"
android:minWidth="48dp"
android:paddingEnd="4dp"
android:paddingStart="4dp"
/>
<Button
android:id="@+id/btnFavourite"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="2dp"
android:background="@drawable/btn_bg_transparent"
android:drawablePadding="4dp"
android:minWidth="48dp"
android:paddingEnd="4dp"
android:paddingStart="4dp"
/>
<ImageButton
android:id="@+id/btnMore"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="2dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/more"
android:minWidth="40dp"
android:src="?attr/btn_more"
/>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/list_item_popup_triangle_bottom"
android:layout_gravity="center_horizontal"
android:visibility="gone"
android:id="@+id/ivTriangleBottom"
/>
</LinearLayout>

View File

@ -68,7 +68,7 @@
/>
<TextView
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvNote"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -232,13 +232,13 @@
android:orientation="vertical"
>
<TextView
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvMentions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvContentWarning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -256,7 +256,7 @@
android:orientation="vertical"
>
<TextView
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -0,0 +1,364 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical"
android:paddingBottom="3dp"
android:paddingTop="3dp"
>
<LinearLayout
android:id="@+id/llBoosted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:background="@drawable/btn_bg_transparent"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/ivBoosted"
android:layout_width="48dp"
android:layout_height="32dp"
android:layout_marginEnd="4dp"
android:scaleType="fitEnd"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tvBoostedAcct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="end"
android:maxLines="1"
android:textColor="?attr/colorAcctSmall"
android:textSize="12sp"
tools:text="who@hoge"
/>
<TextView
android:id="@+id/tvBoostedTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="?attr/colorTimeSmall"
android:textSize="12sp"
tools:text="2017-04-16 09:37:14"
/>
</LinearLayout>
<TextView
android:id="@+id/tvBoosted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="~にブーストされました"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/llFollow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/btn_bg_transparent"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/ivFollow"
android:layout_width="48dp"
android:layout_height="40dp"
android:layout_marginEnd="4dp"
android:contentDescription="@string/thumbnail"
android:scaleType="fitEnd"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
>
<TextView
android:id="@+id/tvFollowerName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Follower Name"
/>
<TextView
android:id="@+id/tvFollowerAcct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorAcctSmall"
android:textSize="12sp"
tools:text="aaaaaaaaaaaaaaaa"
/>
</LinearLayout>
<ImageButton
android:id="@+id/btnFollow"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="4dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/follow"
android:src="?attr/ic_account_add"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/llStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<LinearLayout
android:id="@+id/llTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tvAcct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="end"
android:maxLines="1"
android:textColor="?attr/colorAcctSmall"
android:textSize="12sp"
tools:text="who@hoge"
/>
<TextView
android:id="@+id/tvTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="?attr/colorTimeSmall"
android:textSize="12sp"
tools:text="2017-04-16 09:37:14"
/>
</LinearLayout>
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/ivThumbnail"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_below="@id/llTime"
android:layout_marginEnd="4dp"
android:layout_marginTop="4dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/thumbnail"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/llTime"
android:layout_toEndOf="@id/ivThumbnail"
android:orientation="vertical"
>
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Displayname @username"
/>
<LinearLayout
android:id="@+id/llContentWarning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:baselineAligned="false"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<Button
android:id="@+id/btnContentWarning"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:background="@drawable/btn_bg_ddd"
android:minWidth="40dp"
android:padding="4dp"
tools:text="見る"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
>
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvMentions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvContentWarning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/llContents"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<jp.juggler.subwaytooter.util.MyTextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:lineSpacingMultiplier="1.1"
tools:text="Contents\nContents"
/>
<FrameLayout
android:id="@+id/flMedia"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginTop="3dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/ivMedia1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/btn_bg_ddd"
android:contentDescription="@string/thumbnail"
android:scaleType="centerCrop"
/>
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/ivMedia2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:background="@drawable/btn_bg_ddd"
android:contentDescription="@string/thumbnail"
android:scaleType="centerCrop"
/>
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/ivMedia3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:background="@drawable/btn_bg_ddd"
android:contentDescription="@string/thumbnail"
android:scaleType="centerCrop"
/>
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/ivMedia4"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:background="@drawable/btn_bg_ddd"
android:contentDescription="@string/thumbnail"
android:scaleType="centerCrop"
/>
<ImageButton
android:id="@+id/btnHideMedia"
android:layout_width="32dp"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/hide"
android:src="?attr/btn_close"
/>
</LinearLayout>
<TextView
android:id="@+id/btnShowMedia"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorShowMediaBackground"
android:gravity="center"
android:text="@string/tap_to_show"
android:textColor="?attr/colorShowMediaText"
/>
</FrameLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/llSearchTag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/btnSearchTag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/btn_bg_transparent"
android:textAllCaps="false"
/>
</LinearLayout>
</LinearLayout>

View File

@ -241,7 +241,7 @@
android:layout_height="wrap_content"
app:srl_direction="both">
<ListView
<jp.juggler.subwaytooter.util.MyListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"

View File

@ -188,5 +188,6 @@
<string name="spoil_visibility_for_account">Visibility is spoiled for account.</string>
<string name="contributor">contributor</string>
<string name="thanks_for">Thanks for %1$s</string>
<string name="simple_list">Simple list(app restart required)</string>
</resources>

View File

@ -184,4 +184,5 @@
<string name="spoil_visibility_for_account">公開範囲をアカウントの既定値に狭めました</string>
<string name="contributor">contributor</string>
<string name="thanks_for">Thanks for %1$s</string>
<string name="simple_list">簡略表示(アプリ再起動が必要)</string>
</resources>

View File

@ -185,4 +185,5 @@
<string name="spoil_visibility_for_account">Visibility is spoiled for account.</string>
<string name="contributor">contributor</string>
<string name="thanks_for">Thanks for %1$s</string>
<string name="simple_list">Simple list(app restart required)</string>
</resources>