とりあえずメイン画面の表示だけタブレット対応した

This commit is contained in:
tateisu 2017-05-12 23:10:02 +09:00
parent d4899af01d
commit af2fade576
16 changed files with 1132 additions and 487 deletions

View File

@ -16,7 +16,10 @@ import android.support.v4.text.BidiFormatter;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.support.design.widget.NavigationView;
@ -38,6 +41,7 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -58,11 +62,11 @@ import jp.juggler.subwaytooter.table.MutedApp;
import jp.juggler.subwaytooter.table.SavedAccount;
import jp.juggler.subwaytooter.table.UserRelation;
import jp.juggler.subwaytooter.dialog.ActionsDialog;
import jp.juggler.subwaytooter.util.HTMLDecoder;
import jp.juggler.subwaytooter.util.LinkClickContext;
import jp.juggler.subwaytooter.util.LogCategory;
import jp.juggler.subwaytooter.util.MyClickableSpan;
import jp.juggler.subwaytooter.util.Utils;
import jp.juggler.subwaytooter.view.GravitySnapHelper;
import okhttp3.Request;
import okhttp3.RequestBody;
@ -88,8 +92,7 @@ public class ActMain extends AppCompatActivity
String posted_acct;
long posted_status_id;
@Override
protected void onCreate( Bundle savedInstanceState ){
@Override protected void onCreate( Bundle savedInstanceState ){
super.onCreate( savedInstanceState );
App1.setActivityTheme( this, true );
requestWindowFeature( Window.FEATURE_NO_TITLE );
@ -105,9 +108,13 @@ public class ActMain extends AppCompatActivity
updateColumnStrip();
if( pager_adapter.column_list.size() > 0 ){
if( app_state.column_list.size() > 0 ){
llEmpty.setVisibility( View.GONE );
if( pager_adapter != null ){
onPageSelected( pager.getCurrentItem() );
}else{
resizeColumnWidth();
}
}
AlarmService.startCheck( this );
@ -130,10 +137,10 @@ public class ActMain extends AppCompatActivity
MyClickableSpan.link_callback = link_click_listener;
if( pref.getBoolean( Pref.KEY_DONT_SCREEN_OFF,false )){
getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if( pref.getBoolean( Pref.KEY_DONT_SCREEN_OFF, false ) ){
getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON );
}else{
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().clearFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON );
}
// アカウント設定から戻ってきたらカラムを消す必要があるかもしれない
@ -141,8 +148,8 @@ public class ActMain extends AppCompatActivity
ArrayList< Integer > new_order = new ArrayList<>();
boolean bRemoved = false;
for( int i = 0, ie = pager_adapter.getCount() ; i < ie ; ++ i ){
Column column = pager_adapter.getColumn( i );
for( int i = 0, ie = app_state.column_list.size() ; i < ie ; ++ i ){
Column column = app_state.column_list.get( i );
SavedAccount sa = SavedAccount.loadAccount( log, column.access_info.db_id );
if( sa == null ){
bRemoved = true;
@ -151,9 +158,8 @@ public class ActMain extends AppCompatActivity
}
}
if( bRemoved ){
pager_adapter.setOrder( pager, new_order );
app_state.saveColumnList();
updateColumnStrip();
setOrder( new_order );
}
}
@ -163,7 +169,7 @@ public class ActMain extends AppCompatActivity
if( ! TextUtils.isEmpty( posted_acct ) ){
int refresh_after_toot = pref.getInt( Pref.KEY_REFRESH_AFTER_TOOT, 0 );
if( refresh_after_toot != Pref.RAT_DONT_REFRESH ){
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
SavedAccount a = column.access_info;
if( ! Utils.equalsNullable( a.acct, posted_acct ) ) continue;
column.startRefreshForPost( posted_status_id, refresh_after_toot );
@ -182,7 +188,7 @@ public class ActMain extends AppCompatActivity
handleSentIntent( intent );
}
if( pager_adapter.getCount() == 0 ){
if( app_state.column_list.isEmpty() ){
llEmpty.setVisibility( View.VISIBLE );
}else{
for( Column column : app_state.column_list ){
@ -191,6 +197,8 @@ public class ActMain extends AppCompatActivity
}
}
private void handleSentIntent( final Intent sent_intent ){
AccountPicker.pick( this, false, true, getString( R.string.account_picker_toot ), new AccountPicker.AccountPickerCallback() {
@Override public void onAccountPicked( @NonNull SavedAccount ai ){
@ -261,7 +269,7 @@ public class ActMain extends AppCompatActivity
}
boolean isOrderChanged( ArrayList< Integer > new_order ){
if( new_order.size() != pager_adapter.getCount() ) return true;
if( new_order.size() != app_state.column_list.size() ) return true;
for( int i = 0, ie = new_order.size() ; i < ie ; ++ i ){
if( new_order.get( i ) != i ) return true;
}
@ -283,18 +291,16 @@ public class ActMain extends AppCompatActivity
if( data != null ){
ArrayList< Integer > order = data.getIntegerArrayListExtra( ActColumnList.EXTRA_ORDER );
if( order != null && isOrderChanged( order ) ){
pager_adapter.setOrder( pager, order );
app_state.saveColumnList();
updateColumnStrip();
setOrder( order );
}
if( pager_adapter.column_list.isEmpty() ){
if( app_state.column_list.isEmpty() ){
llEmpty.setVisibility( View.VISIBLE );
}else{
int select = data.getIntExtra( ActColumnList.EXTRA_SELECTION, - 1 );
if( 0 <= select && select < pager_adapter.getCount() ){
pager.setCurrentItem( select, true );
scrollColumnStrip( select );
if( 0 <= select && select < app_state.column_list.size() ){
scrollToColumn( select);
}
}
}
@ -307,12 +313,12 @@ public class ActMain extends AppCompatActivity
if( data != null ){
String search = data.getStringExtra( ActAbout.EXTRA_SEARCH );
if( ! TextUtils.isEmpty( search ) ){
performAddTimeline( true, Column.TYPE_SEARCH, search, true );
performAddTimeline( getDefaultInsertPosition(), true, Column.TYPE_SEARCH, search, true );
}
return;
}
}else if( requestCode == REQUEST_CODE_NICKNAME ){
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.onNicknameUpdated();
}
}else if( requestCode == REQUEST_CODE_POST ){
@ -324,13 +330,11 @@ public class ActMain extends AppCompatActivity
if( data != null ){
app_state.saveColumnList();
int idx = data.getIntExtra( ActColumnCustomize.EXTRA_COLUMN_INDEX, 0 );
ColumnViewHolder vh = pager_adapter.getColumnViewHolder( idx );
if( vh != null ){
vh.showColumnColor();
if( idx >= 0 && idx < app_state.column_list.size() ){
app_state.column_list.get(idx).fireColumnColor();
}
updateColumnStrip();
}
}
}
@ -341,6 +345,8 @@ public class ActMain extends AppCompatActivity
super.onActivityResult( requestCode, resultCode, data );
}
@Override
public void onBackPressed(){
@ -352,15 +358,13 @@ public class ActMain extends AppCompatActivity
}
// カラムが0個ならアプリを終了する
if( pager_adapter.getCount() == 0 ){
if( app_state.column_list.isEmpty() ){
ActMain.this.finish();
return;
}
// カラム設定が開いているならカラム設定を閉じる
ColumnViewHolder vh = pager_adapter.getColumnViewHolder( pager.getCurrentItem() );
if( vh.isColumnSettingShown() ){
vh.closeColumnSetting();
if( closeColumnSetting() ){
return;
}
@ -369,11 +373,17 @@ public class ActMain extends AppCompatActivity
default:
case ActAppSetting.BACK_ASK_ALWAYS:
ActionsDialog dialog = new ActionsDialog();
dialog.addAction( getString( R.string.close_column ), new Runnable() {
@Override public void run(){
if( pager_adapter != null ){
closeColumn( true, pager_adapter.getColumn( pager.getCurrentItem() ) );
}else{
// TODO
}
}
} );
dialog.addAction( getString( R.string.open_column_list ), new Runnable() {
@Override public void run(){
openColumnList();
@ -388,6 +398,7 @@ public class ActMain extends AppCompatActivity
break;
case ActAppSetting.BACK_CLOSE_COLUMN:
if( pager_adapter != null ){
Column column = pager_adapter.getColumn( pager.getCurrentItem() );
if( column != null ){
if( column.dont_close
@ -399,6 +410,9 @@ public class ActMain extends AppCompatActivity
}
closeColumn( false, column );
}
}else{
// TODO
}
break;
case ActAppSetting.BACK_EXIT_APP:
@ -411,6 +425,8 @@ public class ActMain extends AppCompatActivity
}
}
@Override
public boolean onCreateOptionsMenu( Menu menu ){
// Inflate the menu; this adds items to the action bar if it is present.
@ -443,21 +459,21 @@ public class ActMain extends AppCompatActivity
performAccountAdd();
}else if( id == R.id.nav_add_tl_home ){
performAddTimeline( false, Column.TYPE_HOME );
performAddTimeline(getDefaultInsertPosition(), false, Column.TYPE_HOME );
}else if( id == R.id.nav_add_tl_local ){
performAddTimeline( true, Column.TYPE_LOCAL );
performAddTimeline( getDefaultInsertPosition(),true, Column.TYPE_LOCAL );
}else if( id == R.id.nav_add_tl_federate ){
performAddTimeline( true, Column.TYPE_FEDERATE );
performAddTimeline( getDefaultInsertPosition(),true, Column.TYPE_FEDERATE );
}else if( id == R.id.nav_add_favourites ){
performAddTimeline( false, Column.TYPE_FAVOURITES );
performAddTimeline( getDefaultInsertPosition(),false, Column.TYPE_FAVOURITES );
// }else if( id == R.id.nav_add_reports ){
// performAddTimeline(Column.TYPE_REPORTS );
}else if( id == R.id.nav_add_statuses ){
performAddTimeline( false, Column.TYPE_PROFILE );
performAddTimeline( getDefaultInsertPosition(),false, Column.TYPE_PROFILE );
}else if( id == R.id.nav_add_notifications ){
performAddTimeline( false, Column.TYPE_NOTIFICATIONS );
performAddTimeline( getDefaultInsertPosition(),false, Column.TYPE_NOTIFICATIONS );
}else if( id == R.id.nav_app_setting ){
ActAppSetting.open( this, REQUEST_APP_SETTING );
@ -469,7 +485,7 @@ public class ActMain extends AppCompatActivity
openColumnList();
}else if( id == R.id.nav_add_tl_search ){
performAddTimeline( true, Column.TYPE_SEARCH, "", false );
performAddTimeline( getDefaultInsertPosition(), true, Column.TYPE_SEARCH, "", false );
}else if( id == R.id.nav_app_about ){
openAppAbout();
@ -481,13 +497,13 @@ public class ActMain extends AppCompatActivity
finish();
}else if( id == R.id.nav_add_mutes ){
performAddTimeline( false, Column.TYPE_MUTES );
performAddTimeline( getDefaultInsertPosition(),false, Column.TYPE_MUTES );
}else if( id == R.id.nav_add_blocks ){
performAddTimeline( false, Column.TYPE_BLOCKS );
performAddTimeline( getDefaultInsertPosition(),false, Column.TYPE_BLOCKS );
}else if( id == R.id.nav_follow_requests ){
performAddTimeline( false, Column.TYPE_FOLLOW_REQUESTS );
performAddTimeline( getDefaultInsertPosition(),false, Column.TYPE_FOLLOW_REQUESTS );
}else if( id == R.id.nav_muted_app ){
startActivity( new Intent( this, ActMutedApp.class ) );
@ -529,6 +545,10 @@ public class ActMain extends AppCompatActivity
View vFooterDivider1;
View vFooterDivider2;
RecyclerView tablet_pager;
TabletColumnPagerAdapter tablet_pager_adapter;
LinearLayoutManager tablet_layout_manager;
void initUI(){
setContentView( R.layout.act_main );
@ -560,11 +580,38 @@ public class ActMain extends AppCompatActivity
svColumnStrip.setHorizontalFadingEdgeEnabled( true );
// ViewPager
DisplayMetrics dm = getResources().getDisplayMetrics();
//
int sw = dm.widthPixels;
// int sh = dm.heightPixels;
// int short_side = ( sw < sh ? sw : sh );
//
// float density = dm.density;
// int column_w_min = (int) ( 0.5f + 320f * density );
pager = (ViewPager) findViewById( R.id.viewPager );
tablet_pager = (RecyclerView) findViewById( R.id.rvPager );
//noinspection ConstantIfStatement
if( false ){
tablet_pager.setVisibility( View.GONE );
// SmartPhone mode
pager_adapter = new ColumnPagerAdapter( this );
pager.setAdapter( pager_adapter );
pager.addOnPageChangeListener( this );
}else{
pager.setVisibility( View.GONE );
// tablet mode
tablet_pager_adapter = new TabletColumnPagerAdapter( this );
tablet_layout_manager = new LinearLayoutManager( this, LinearLayoutManager.HORIZONTAL, false );
tablet_pager.setAdapter( tablet_pager_adapter );
tablet_pager.setLayoutManager( tablet_layout_manager );
///////tablet_pager.setHasFixedSize( true );
// tablet_pager.addItemDecoration( new TabletColumnDivider( this ) );
new GravitySnapHelper(Gravity.START).attachToRecyclerView( tablet_pager );
}
showFooterColor();
}
@ -581,7 +628,7 @@ public class ActMain extends AppCompatActivity
viewRoot.setTag( i );
viewRoot.setOnClickListener( new View.OnClickListener() {
@Override public void onClick( View v ){
onClickColumnStrip( (Integer) v.getTag() );
scrollToColumn( (Integer) v.getTag() );
}
} );
viewRoot.setContentDescription( column.getColumnName( true ) );
@ -647,9 +694,7 @@ public class ActMain extends AppCompatActivity
}
private void onClickColumnStrip( int idx ){
pager.setCurrentItem( idx, true );
}
public void performAccountAdd(){
LoginForm.showLoginForm( this, null, new LoginForm.LoginFormCallback() {
@ -714,7 +759,8 @@ public class ActMain extends AppCompatActivity
if( a != null ){
// 疑似アカウントが追加された
Utils.showToast( ActMain.this, false, R.string.server_confirmed );
addColumn( a, Column.TYPE_LOCAL );
int pos = app_state.column_list.size();
addColumn( pos, a, Column.TYPE_LOCAL );
dialog.dismiss();
}
@ -815,7 +861,7 @@ public class ActMain extends AppCompatActivity
, new AccountPicker.AccountPickerCallback() {
@Override
public void onAccountPicked( @NonNull final SavedAccount ai ){
openStatus( ai, status_id );
openStatus( getDefaultInsertPosition(),ai, status_id );
}
} );
@ -858,10 +904,10 @@ public class ActMain extends AppCompatActivity
startGetAccount( ai, host, user, new GetAccountCallback() {
@Override public void onGetAccount( TootAccount who ){
if( who != null ){
performOpenUser( ai, who );
performOpenUser(getDefaultInsertPosition(), ai, who );
return;
}
openChromeTab( ai, uri.toString(), true );
openChromeTab( getDefaultInsertPosition(),ai, uri.toString(), true );
}
} );
}
@ -883,7 +929,7 @@ public class ActMain extends AppCompatActivity
long db_id = Long.parseLong( sv, 10 );
SavedAccount account = SavedAccount.loadAccount( log, db_id );
if( account != null ){
Column column = addColumn( account, Column.TYPE_NOTIFICATIONS );
Column column = addColumn( getDefaultInsertPosition(), account, Column.TYPE_NOTIFICATIONS );
if( ! column.bInitialLoading ){
column.startLoading();
}
@ -1007,7 +1053,7 @@ public class ActMain extends AppCompatActivity
reloadAccountSetting();
// 自動でリロードする
for( Column c : pager_adapter.column_list ){
for( Column c : app_state.column_list ){
if( c.access_info.acct.equals( sa.acct ) ){
c.startLoading();
}
@ -1025,7 +1071,7 @@ public class ActMain extends AppCompatActivity
}
Utils.showToast( ActMain.this, false, R.string.account_confirmed );
AlarmService.startCheck( ActMain.this );
addColumn( account, Column.TYPE_HOME );
addColumn( getDefaultInsertPosition(),account, Column.TYPE_HOME );
}
}
}
@ -1044,7 +1090,7 @@ public class ActMain extends AppCompatActivity
void reloadAccountSetting(){
ArrayList< SavedAccount > done_list = new ArrayList<>();
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
SavedAccount a = column.access_info;
if( done_list.contains( a ) ) continue;
done_list.add( a );
@ -1055,7 +1101,7 @@ public class ActMain extends AppCompatActivity
void reloadAccountSetting( SavedAccount account ){
ArrayList< SavedAccount > done_list = new ArrayList<>();
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
SavedAccount a = column.access_info;
if( ! Utils.equalsNullable( a.acct, account.acct ) ) continue;
if( done_list.contains( a ) ) continue;
@ -1084,72 +1130,88 @@ public class ActMain extends AppCompatActivity
.show();
return;
}
int page_delete = app_state.column_list.indexOf( column );
if( pager_adapter != null){
int page_showing = pager.getCurrentItem();
int page_delete = pager_adapter.column_list.indexOf( column );
pager_adapter.removeColumn( pager, column );
app_state.saveColumnList();
updateColumnStrip();
if( pager_adapter.getCount() == 0 ){
removeColumn( column );
if( app_state.column_list.isEmpty() ){
llEmpty.setVisibility( View.VISIBLE );
}else if( page_showing > 0 && page_showing == page_delete ){
pager.setCurrentItem( page_showing - 1, true );
scrollColumnStrip( page_showing - 1 );
}else if( page_delete > 0 && page_showing == page_delete ){
scrollToColumn( page_showing - 1 );
}
}else{
removeColumn( column );
if( app_state.column_list.isEmpty() ){
llEmpty.setVisibility( View.VISIBLE );
}else{
// TODO 一つ左のカラムが見えるようにしたい
if( page_delete > 0 ){
scrollToColumn( page_delete -1 );
}
}
}
}
//////////////////////////////////////////////////////////////
// カラム追加系
public Column addColumn( SavedAccount ai, int type, Object... params ){
public Column addColumn( int index, SavedAccount ai, int type, Object... params ){
// 既に同じカラムがあればそこに移動する
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
if( column.isSameSpec( ai, type, params ) ){
pager.setCurrentItem( pager_adapter.column_list.indexOf( column ), true );
index = app_state.column_list.indexOf( column );
scrollToColumn( index );
return column;
}
}
//
llEmpty.setVisibility( View.GONE );
//
Column col = new Column( app_state, ai, this, type, params );
int idx = pager_adapter.addColumn( pager, col );
app_state.saveColumnList();
updateColumnStrip();
pager.setCurrentItem( idx, true );
index = addColumn( col, index );
scrollToColumn( index );
return col;
}
void performOpenUser( @NonNull SavedAccount access_info, @NonNull TootAccount user ){
void performOpenUser( int pos,@NonNull SavedAccount access_info, @NonNull TootAccount user ){
if( access_info.isPseudo() ){
Utils.showToast( this, false, R.string.not_available_for_pseudo_account );
}else{
addColumn( access_info, Column.TYPE_PROFILE, user.id );
addColumn( pos,access_info, Column.TYPE_PROFILE, user.id );
}
}
public void performOpenUserFromAnotherAccount( final TootAccount who, ArrayList< SavedAccount > account_list_non_pseudo_same_instance ){
public void performOpenUserFromAnotherAccount( final int pos, final TootAccount who, ArrayList< SavedAccount > account_list_non_pseudo_same_instance ){
AccountPicker.pick( this, false, false
, getString( R.string.account_picker_open_user_who, AcctColor.getNickname( who.acct ) )
, account_list_non_pseudo_same_instance
, new AccountPicker.AccountPickerCallback() {
@Override public void onAccountPicked( @NonNull SavedAccount ai ){
addColumn( ai, Column.TYPE_PROFILE, who.id );
addColumn( pos,ai, Column.TYPE_PROFILE, who.id );
}
} );
}
private void performAddTimeline( boolean bAllowPseudo, final int type, final Object... args ){
private void performAddTimeline( final int pos, boolean bAllowPseudo, final int type, final Object... args ){
AccountPicker.pick( this, bAllowPseudo, true
, getString( R.string.account_picker_add_timeline_of, Column.getColumnTypeName( this, type ) )
, new AccountPicker.AccountPickerCallback() {
@Override public void onAccountPicked( @NonNull SavedAccount ai ){
switch( type ){
default:
addColumn( ai, type, args );
addColumn( pos,ai, type, args );
break;
case Column.TYPE_PROFILE:
addColumn( ai, type, ai.id );
addColumn(pos, ai, type, ai.id );
break;
}
}
@ -1158,7 +1220,7 @@ public class ActMain extends AppCompatActivity
public void performMuteApp( @NonNull TootApplication application ){
MutedApp.save( application.name );
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.removeMuteApp();
}
Utils.showToast( ActMain.this, false, R.string.app_was_muted );
@ -1245,7 +1307,7 @@ public class ActMain extends AppCompatActivity
static final Pattern reUserPage = Pattern.compile( "\\Ahttps://([^/]+)/@([^?#/]+)\\z" );
static final Pattern reStatusPage = Pattern.compile( "\\Ahttps://([^/]+)/@([^?#/]+)/(\\d+)\\z" );
public void openChromeTab( final SavedAccount access_info, final String url, boolean noIntercept ){
public void openChromeTab( final int pos,final SavedAccount access_info, final String url, boolean noIntercept ){
try{
log.d( "openChromeTab url=%s", url );
@ -1257,10 +1319,10 @@ public class ActMain extends AppCompatActivity
String host = m.group( 1 );
String tag = Uri.decode( m.group( 2 ) );
if( host.equalsIgnoreCase( access_info.host ) ){
openHashTag( access_info, tag );
openHashTag( pos,access_info, tag );
return;
}else{
openHashTagOtherInstance( access_info, url, host, tag );
openHashTagOtherInstance( pos,access_info, url, host, tag );
return;
}
}
@ -1273,10 +1335,10 @@ public class ActMain extends AppCompatActivity
final String host = m.group( 1 );
final long status_id = Long.parseLong( m.group( 3 ), 10 );
if( host.equalsIgnoreCase( access_info.host ) ){
openStatus( access_info, status_id );
openStatus(pos, access_info, status_id );
return;
}else{
openStatusOtherInstance( access_info, url, host, status_id );
openStatusOtherInstance( pos,access_info, url, host, status_id );
return;
}
}catch( Throwable ex ){
@ -1294,10 +1356,10 @@ public class ActMain extends AppCompatActivity
startGetAccount( access_info, host, user, new GetAccountCallback() {
@Override public void onGetAccount( TootAccount who ){
if( who != null ){
performOpenUser( access_info, who );
performOpenUser( pos,access_info, who );
return;
}
openChromeTab( access_info, url, true );
openChromeTab( pos,access_info, url, true );
}
} );
return;
@ -1329,21 +1391,21 @@ public class ActMain extends AppCompatActivity
}
}
public void openStatus( @NonNull SavedAccount access_info, @NonNull TootStatus status ){
openStatus( access_info, status.id );
public void openStatus( int pos,@NonNull SavedAccount access_info, @NonNull TootStatus status ){
openStatus( pos,access_info, status.id );
}
public void openStatus( @NonNull SavedAccount access_info, long status_id ){
addColumn( access_info, Column.TYPE_CONVERSATION, status_id );
public void openStatus( int pos, @NonNull SavedAccount access_info, long status_id ){
addColumn( pos,access_info, Column.TYPE_CONVERSATION, status_id );
}
private void openStatusOtherInstance( final SavedAccount access_info, final String url, final String host, final long status_id ){
private void openStatusOtherInstance( final int pos,final SavedAccount access_info, final String url, final String host, final long status_id ){
ActionsDialog dialog = new ActionsDialog();
// ブラウザで表示する
dialog.addAction( getString( R.string.open_web_on_host, host ), new Runnable() {
@Override public void run(){
openChromeTab( access_info, url, true );
openChromeTab( pos,access_info, url, true );
}
} );
@ -1366,7 +1428,7 @@ public class ActMain extends AppCompatActivity
final SavedAccount _a = a;
dialog.addAction( getString( R.string.open_in_account, a.acct ), new Runnable() {
@Override public void run(){
openStatus( _a, status_id );
openStatus( pos, _a, status_id );
}
} );
}
@ -1377,7 +1439,7 @@ public class ActMain extends AppCompatActivity
@Override public void run(){
SavedAccount sa = addPseudoAccount( host );
if( sa != null ){
openStatus( sa, status_id );
openStatus( pos,sa, status_id );
}
}
} );
@ -1386,19 +1448,19 @@ public class ActMain extends AppCompatActivity
dialog.show( this, getString( R.string.open_status_from ) );
}
public void openHashTag( SavedAccount access_info, String tag ){
addColumn( access_info, Column.TYPE_HASHTAG, tag );
public void openHashTag( int pos, SavedAccount access_info, String tag ){
addColumn( pos, access_info, Column.TYPE_HASHTAG, tag );
}
// 他インスタンスのハッシュタグの表示
private void openHashTagOtherInstance( final SavedAccount access_info, final String url, final String host, final String tag ){
private void openHashTagOtherInstance( final int pos, final SavedAccount access_info, final String url, final String host, final String tag ){
ActionsDialog dialog = new ActionsDialog();
// ブラウザで表示する
dialog.addAction( getString( R.string.open_web_on_host, host ), new Runnable() {
@Override public void run(){
openChromeTab( access_info, url, true );
openChromeTab( pos,access_info, url, true );
}
} );
@ -1423,7 +1485,7 @@ public class ActMain extends AppCompatActivity
final SavedAccount _a = a;
dialog.addAction( getString( R.string.open_in_account, a.acct ), new Runnable() {
@Override public void run(){
openHashTag( _a, tag );
openHashTag( pos, _a, tag );
}
} );
}
@ -1433,7 +1495,7 @@ public class ActMain extends AppCompatActivity
@Override public void run(){
SavedAccount sa = addPseudoAccount( host );
if( sa != null ){
openHashTag( sa, tag );
openHashTag( pos,sa, tag );
}
}
} );
@ -1444,20 +1506,43 @@ public class ActMain extends AppCompatActivity
}
final MyClickableSpan.LinkClickCallback link_click_listener = new MyClickableSpan.LinkClickCallback() {
@Override public void onClickLink( LinkClickContext lcc, String url ){
openChromeTab( (SavedAccount) lcc, url, false );
@Override public void onClickLink( View view,LinkClickContext lcc, String url ){
Column column = null;
while( view != null ){
Object tag = view.getTag();
if( tag instanceof ItemViewHolder ){
column = ((ItemViewHolder)tag).column;
break;
}else if( tag instanceof HeaderViewHolder ){
column = ( (HeaderViewHolder) tag ).column;
break;
}else if( tag instanceof TabletColumnViewHolder ){
column = ( (TabletColumnViewHolder) tag ).vh.column;
break;
}else{
view = (View) view.getParent();
}
}
openChromeTab( nextPosition( column ),(SavedAccount) lcc, url, false );
}
};
private void performTootButton(){
if( pager_adapter != null){
Column c = pager_adapter.getColumn( pager.getCurrentItem() );
if( c != null ){
if( c.access_info.isPseudo() ){
Utils.showToast( this, false, R.string.not_available_for_pseudo_account );
}else{
if( c != null && ! c.access_info.isPseudo() ){
ActPost.open( this, REQUEST_CODE_POST, c.access_info.db_id, "" );
}
}
AccountPicker.pick( this, false, true, getString( R.string.account_picker_toot ), new AccountPicker.AccountPickerCallback() {
@Override public void onAccountPicked( @NonNull SavedAccount ai ){
ActPost.open( ActMain.this, REQUEST_CODE_POST, ai.db_id, "" );
}
} );
}
public void performReply( SavedAccount account, TootStatus status ){
@ -1482,7 +1567,7 @@ public class ActMain extends AppCompatActivity
/////////////////////////////////////////////////////////////////////////
private void showColumnMatchAccount( SavedAccount account ){
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
if( account.acct.equals( column.access_info.acct ) ){
column.fireShowContent();
}
@ -1603,7 +1688,7 @@ public class ActMain extends AppCompatActivity
}
}
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.findStatus( access_info, new_status.id, new Column.StatusEntryCallback() {
@Override
public void onIterate( TootStatus status ){
@ -1768,7 +1853,7 @@ public class ActMain extends AppCompatActivity
}
}
}
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.findStatus( access_info, new_status.id, new Column.StatusEntryCallback() {
@Override public void onIterate( TootStatus status ){
status.reblogged = new_status.reblogged;
@ -1804,15 +1889,12 @@ public class ActMain extends AppCompatActivity
// column list
private void openColumnList(){
if( pager_adapter != null ){
ActColumnList.open( this, pager.getCurrentItem(), REQUEST_CODE_COLUMN_LIST );
}else{
ActColumnList.open( this, -1, REQUEST_CODE_COLUMN_LIST );
}
}
// private void dumpColumnList(){
// for( int i = 0, ie = pager_adapter.column_list.size() ; i < ie ; ++ i ){
// Column column = pager_adapter.column_list.get( i );
// log.d( "dumpColumnList [%s]%s %s", i, column.access_info.acct, column.getColumnName( true ) );
// }
// }
////////////////////////////////////////////////////////////////////////////
@ -1827,8 +1909,7 @@ public class ActMain extends AppCompatActivity
}
// relationshipを取得
@NonNull
RelationResult loadRelation1( TootApiClient client, SavedAccount access_info, long who_id ){
@NonNull RelationResult loadRelation1( TootApiClient client, SavedAccount access_info, long who_id ){
RelationResult rr = new RelationResult();
TootApiResult r2 = rr.result = client.request( "/api/v1/accounts/relationships?id=" + who_id );
if( r2 != null && r2.array != null ){
@ -2206,11 +2287,11 @@ public class ActMain extends AppCompatActivity
Utils.showToast( ActMain.this, false, bMute ? R.string.mute_succeeded : R.string.unmute_succeeded );
if( bMute ){
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.removeStatusByAccount( access_info, who.id );
}
}else{
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.removeFromMuteList( access_info, who.id );
}
}
@ -2274,7 +2355,7 @@ public class ActMain extends AppCompatActivity
// cancelled.
}else if( relation != null ){
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
if( bBlock ){
column.removeStatusByAccount( access_info, who.id );
}else{
@ -2331,7 +2412,7 @@ public class ActMain extends AppCompatActivity
// cancelled.
}else if( result.object != null ){
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.removeFollowRequest( access_info, who.id );
}
@ -2378,7 +2459,7 @@ public class ActMain extends AppCompatActivity
//cancelled.
}else if( result.object != null ){
Utils.showToast( ActMain.this, false, R.string.delete_succeeded );
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
column.removeStatus( access_info, status_id );
}
}else{
@ -2547,7 +2628,7 @@ public class ActMain extends AppCompatActivity
//cancelled.
}else if( result.object != null ){
// ok. empty object will be returned.
for( Column column : pager_adapter.column_list ){
for( Column column : app_state.column_list ){
if( column.column_type == Column.TYPE_NOTIFICATIONS
&& column.access_info.acct.equals( target_account.acct )
){
@ -2626,12 +2707,12 @@ public class ActMain extends AppCompatActivity
if( status == null ) return;
AccountPicker.pick( this, false, false
, getString( R.string.account_picker_boost )
, makeAccountListNonPseudo(log)
, makeAccountListNonPseudo( log )
, new AccountPicker.AccountPickerCallback() {
@Override public void onAccountPicked( @NonNull SavedAccount ai ){
performBoost(
ai
, !ai.host.equalsIgnoreCase( access_info.host )
, ! ai.host.equalsIgnoreCase( access_info.host )
, true
, status
, false
@ -2676,4 +2757,171 @@ public class ActMain extends AppCompatActivity
}
} );
}
private boolean closeColumnSetting(){
if( pager_adapter != null){
ColumnViewHolder vh = pager_adapter.getColumnViewHolder( pager.getCurrentItem() );
if( vh.isColumnSettingShown() ){
vh.closeColumnSetting();
return true;
}
}else{
for( int i = 0, ie = tablet_layout_manager.getChildCount() ; i < ie ; ++ i ){
View v = tablet_layout_manager.getChildAt( i );
Object o = v.getTag();
if( o instanceof TabletColumnViewHolder ){
TabletColumnViewHolder holder = (TabletColumnViewHolder) o;
if( holder.vh.isColumnSettingShown() ){
holder.vh.closeColumnSetting();
return true;
}
}
}
}
return false;
}
private int getDefaultInsertPosition(){
if( pager_adapter != null ){
return 1+ pager.getCurrentItem();
}else{
return Integer.MAX_VALUE;
}
}
int nextPosition( Column column ){
if( column != null ){
int pos = app_state.column_list.indexOf( column );
if( pos != - 1 ) return pos + 1;
}
return getDefaultInsertPosition();
}
private int addColumn( Column column, int index ){
int size = app_state.column_list.size();
if( index > size ) index = size;
if( pager_adapter != null){
pager.setAdapter( null );
app_state.column_list.add( index, column );
pager.setAdapter( pager_adapter );
}else{
app_state.column_list.add( index, column );
resizeColumnWidth();
}
app_state.saveColumnList();
updateColumnStrip();
return index;
}
private void removeColumn( Column column ){
int idx_column = app_state.column_list.indexOf( column );
if( idx_column == - 1 ) return;
if( pager_adapter != null){
pager.setAdapter( null );
app_state.column_list.remove( idx_column ).dispose();
pager.setAdapter( pager_adapter );
}else{
app_state.column_list.remove( idx_column ).dispose();
resizeColumnWidth();
}
app_state.saveColumnList();
updateColumnStrip();
}
private void setOrder( ArrayList< Integer > new_order ){
if( pager_adapter != null ){
pager.setAdapter( null );
}
ArrayList< Column > tmp_list = new ArrayList<>();
HashSet< Integer > used_set = new HashSet<>();
for( Integer i : new_order ){
used_set.add( i );
tmp_list.add( app_state.column_list.get( i ) );
}
for( int i = 0, ie = app_state.column_list.size() ; i < ie ; ++ i ){
if( used_set.contains( i ) ) continue;
app_state.column_list.get( i ).dispose();
}
app_state.column_list.clear();
app_state.column_list.addAll( tmp_list );
if( pager_adapter != null ){
pager.setAdapter( pager_adapter );
}else{
resizeColumnWidth();
}
app_state.saveColumnList();
updateColumnStrip();
}
int nScreenColumn;
private void resizeColumnWidth(){
// TODO カラム幅を調節する
DisplayMetrics dm = getResources().getDisplayMetrics();
//
int sw = dm.widthPixels;
// int sh = dm.heightPixels;
// int short_side = ( sw < sh ? sw : sh );
//
float density = dm.density;
int column_w_min = (int) ( 0.5f + 320f * density );
int column_w_max = (int) ( 0.5f + 360f * density );
if( sw >= column_w_min * 2 ){
nScreenColumn = sw / column_w_min;
if( nScreenColumn > app_state.column_list.size() ){
nScreenColumn = app_state.column_list.size();
}
int column_w = sw/ nScreenColumn;
if( column_w > column_w_max ){
column_w = column_w_max;
}
tablet_pager_adapter.setColumnWidth( column_w );
}else{
tablet_pager_adapter.setColumnWidth( sw );
}
// 並べ直す
tablet_pager_adapter.notifyDataSetChanged();
}
private void scrollToColumn( int index ){
scrollColumnStrip( index );
if( pager_adapter != null ){
pager.setCurrentItem( index, true );
}else{
// 指定されたカラムが画面内に表示される最低限の移動ですませたい
if( nScreenColumn >0 ){
int vs = tablet_layout_manager.findFirstVisibleItemPosition();
if( vs != RecyclerView.NO_POSITION ){
if( index < vs ){
tablet_pager.smoothScrollToPosition( index );
}else{
int ve = vs + nScreenColumn - 1;
if( index > ve ){
tablet_pager.smoothScrollToPosition( index - ( nScreenColumn - 1 ) );
}
}
}
}
}
}
}

View File

@ -714,6 +714,11 @@ class Column implements StreamReader.Callback {
if( holder != null ) holder.showColumnHeader();
}
};
private final Runnable proc_showColumnColor = new Runnable() {
@Override public void run(){
if( holder != null ) holder.showColumnColor();
}
};
void fireShowContent(){
Utils.runOnMainThread( proc_showContent );
@ -724,6 +729,11 @@ class Column implements StreamReader.Callback {
Utils.runOnMainThread( proc_showColumnHeader );
}
void fireColumnColor(){
Utils.runOnMainThread( proc_showColumnColor );
}
private AsyncTask< Void, Void, TootApiResult > last_task;
private void cancelLastTask(){

View File

@ -37,46 +37,6 @@ class ColumnPagerAdapter extends PagerAdapter {
return holder_list.get( idx );
}
int addColumn( ViewPager pager, Column column ){
return addColumn( pager, column, pager.getCurrentItem() + 1 );
}
int addColumn( ViewPager pager, Column column, int index ){
int size = column_list.size();
if( index > size ) index = size;
pager.setAdapter( null );
column_list.add( index, column );
pager.setAdapter( this );
return index;
}
void removeColumn( ViewPager pager, Column column ){
int idx_column = column_list.indexOf( column );
if( idx_column == - 1 ) return;
pager.setAdapter( null );
column_list.remove( idx_column ).dispose();
pager.setAdapter( this );
}
void setOrder( ViewPager pager, ArrayList< Integer > order ){
pager.setAdapter( null );
ArrayList< Column > tmp_list = new ArrayList<>();
HashSet< Integer > used_set = new HashSet<>();
for( Integer i : order ){
used_set.add( i );
tmp_list.add( column_list.get( i ) );
}
for( int i = 0, ie = column_list.size() ; i < ie ; ++ i ){
if( used_set.contains( i ) ) continue;
column_list.get( i ).dispose();
}
column_list.clear();
column_list.addAll( tmp_list );
pager.setAdapter( this );
}
@Override public CharSequence getPageTitle( int page_idx ){
return getColumn( page_idx).getColumnName( false );
@ -108,7 +68,7 @@ class ColumnPagerAdapter extends PagerAdapter {
ColumnViewHolder holder = holder_list.get( page_idx );
holder_list.remove( page_idx );
if( holder != null ){
holder.is_destroyed.set( true );
holder.onPageDestroy( view );
}
}

View File

@ -54,6 +54,7 @@ class ColumnViewHolder
void onPageDestroy( @SuppressWarnings("UnusedParameters") View root ){
log.d( "onPageDestroy:%s", column.getColumnName( true ) );
is_destroyed.set( true );
saveScrollPosition();

View File

@ -33,6 +33,7 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
@NonNull private final TootAccount who;
@Nullable private final TootStatus status;
@NonNull private final UserRelation relation;
@NonNull private final Column column;
private final Dialog dialog;
@ -41,15 +42,16 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
DlgContextMenu(
@NonNull ActMain activity
, @NonNull SavedAccount access_info
, @NonNull Column column
, @NonNull TootAccount who
, @Nullable TootStatus status
, int column_type
){
this.activity = activity;
this.access_info = access_info;
this.column = column;
this.access_info = column.access_info;
this.who = who;
this.status = status;
int column_type = column.column_type;
this.relation = UserRelation.load( access_info.db_id, who.id );
@ -235,11 +237,13 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
dialog.dismiss();
int pos = activity.nextPosition( column ) ;
switch( v.getId() ){
case R.id.btnStatusWebPage:
if( status != null ){
activity.openChromeTab( access_info, status.url, true );
activity.openChromeTab(pos,access_info, status.url, true );
}
break;
@ -318,13 +322,13 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
case R.id.btnBoostedBy:
if( status != null ){
activity.addColumn( access_info, Column.TYPE_BOOSTED_BY, status.id );
activity.addColumn( pos,access_info, Column.TYPE_BOOSTED_BY, status.id );
}
break;
case R.id.btnFavouritedBy:
if( status != null ){
activity.addColumn( access_info, Column.TYPE_FAVOURITED_BY, status.id );
activity.addColumn( pos,access_info, Column.TYPE_FAVOURITED_BY, status.id );
}
break;
@ -371,7 +375,7 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
break;
case R.id.btnProfile:
activity.performOpenUser( access_info, who );
activity.performOpenUser( pos,access_info, who );
break;
case R.id.btnSendMessage:
@ -379,7 +383,7 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
break;
case R.id.btnAccountWebPage:
activity.openChromeTab( access_info, who.url, true );
activity.openChromeTab( pos, access_info, who.url, true );
break;
case R.id.btnFollowRequestOK:
@ -399,7 +403,7 @@ class DlgContextMenu implements View.OnClickListener, View.OnLongClickListener {
break;
case R.id.btnOpenProfileFromAnotherAccount:
activity.performOpenUserFromAnotherAccount( who, account_list_non_pseudo_same_instance );
activity.performOpenUserFromAnotherAccount( pos,who, account_list_non_pseudo_same_instance );
break;
case R.id.btnNickname:

View File

@ -17,7 +17,7 @@ import jp.juggler.subwaytooter.view.MyLinkMovementMethod;
import jp.juggler.subwaytooter.view.MyNetworkImageView;
class HeaderViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final Column column;
final Column column;
private final ActMain activity;
private final SavedAccount access_info;
@ -106,12 +106,13 @@ class HeaderViewHolder implements View.OnClickListener, View.OnLongClickListener
@Override
public void onClick( View v ){
switch( v.getId() ){
case R.id.ivBackground:
if( who != null ){
// 強制的にブラウザで開く
activity.openChromeTab( access_info, who.url, true );
activity.openChromeTab( activity.nextPosition( column ), access_info, who.url, true );
}
break;
@ -135,13 +136,13 @@ class HeaderViewHolder implements View.OnClickListener, View.OnLongClickListener
case R.id.btnMore:
if( who != null ){
new DlgContextMenu( activity, access_info, who, null, column.column_type ).show();
new DlgContextMenu( activity, column, who, null ).show();
}
break;
case R.id.btnFollow:
if( who != null ){
new DlgContextMenu( activity, access_info, who, null, column.column_type ).show();
new DlgContextMenu( activity, column, who, null ).show();
}
break;

View File

@ -385,6 +385,9 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
}
@Override public void onClick( View v ){
int pos = activity.nextPosition( column ) ;
switch( v.getId() ){
case R.id.btnHideMedia:
MediaShown.save( access_info.host, status.id, false );
@ -415,33 +418,33 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
case R.id.ivThumbnail:
if( access_info.isPseudo() ){
new DlgContextMenu( activity, access_info, account_thumbnail, null, column.column_type ).show();
new DlgContextMenu( activity, column, account_thumbnail, null ).show();
}else{
activity.performOpenUser( access_info, account_thumbnail );
activity.performOpenUser( pos,access_info, account_thumbnail );
}
break;
case R.id.llBoosted:
if( access_info.isPseudo() ){
new DlgContextMenu( activity, access_info, account_boost, null, column.column_type ).show();
new DlgContextMenu( activity, column, account_boost, null ).show();
}else{
activity.performOpenUser( access_info, account_boost );
activity.performOpenUser( pos,access_info, account_boost );
}
break;
case R.id.llFollow:
if( access_info.isPseudo() ){
new DlgContextMenu( activity, access_info, account_follow, null, column.column_type ).show();
new DlgContextMenu( activity, column, account_follow, null ).show();
}else{
activity.performOpenUser( access_info, account_follow );
activity.performOpenUser( pos,access_info, account_follow );
}
break;
case R.id.btnFollow:
new DlgContextMenu( activity, access_info, account_follow, null, column.column_type ).show();
new DlgContextMenu( activity, column, account_follow, null ).show();
break;
case R.id.btnSearchTag:
if( search_tag != null ){
activity.openHashTag( access_info, search_tag );
activity.openHashTag( pos,access_info, search_tag );
}else if( gap != null ){
column.startGap( gap, position );
}
@ -453,7 +456,7 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
switch( v.getId() ){
case R.id.ivThumbnail:
new DlgContextMenu( activity, access_info, account_thumbnail, null, column.column_type ).show();
new DlgContextMenu( activity, column, account_thumbnail, null ).show();
return true;
case R.id.btnFollow:
@ -481,7 +484,8 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener {
sv = a.url;
}
}
activity.openChromeTab( access_info, sv, false );
int pos = activity.nextPosition( column ) ;
activity.openChromeTab(pos, access_info, sv, false );
}catch( Throwable ex ){
ex.printStackTrace();
}

View File

@ -113,7 +113,7 @@ class StatusButtons implements View.OnClickListener, View.OnLongClickListener {
if( close_window != null ) close_window.dismiss();
switch( v.getId() ){
case R.id.btnConversation:
activity.openStatus( access_info, status );
activity.openStatus( activity.nextPosition( column ), access_info, status );
break;
case R.id.btnReply:
if( access_info.isPseudo() ){
@ -152,7 +152,7 @@ class StatusButtons implements View.OnClickListener, View.OnLongClickListener {
break;
case R.id.btnMore:
new DlgContextMenu( activity, access_info, status.account, status, column.column_type ).show();
new DlgContextMenu( activity, column, status.account, status ).show();
break;
case R.id.btnFollow2:

View File

@ -0,0 +1,54 @@
package jp.juggler.subwaytooter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
class TabletColumnPagerAdapter extends RecyclerView.Adapter<TabletColumnViewHolder >{
private final ActMain activity;
private final LayoutInflater mLayoutInflater;
private final List<Column> column_list;
TabletColumnPagerAdapter( ActMain activity ){
super();
this.activity = activity;
this.column_list = activity.app_state.column_list;
mLayoutInflater = LayoutInflater.from( activity );
}
@Override public int getItemCount(){
return column_list.size();
}
private int mColumnWidth = 0;
void setColumnWidth( int width ){
mColumnWidth = width;
}
@Override public TabletColumnViewHolder onCreateViewHolder( ViewGroup parent, int viewType ){
View v = mLayoutInflater.inflate( R.layout.page_column, parent, false );
return new TabletColumnViewHolder( v );
}
@Override public void onBindViewHolder( TabletColumnViewHolder holder, int position ){
if( mColumnWidth > 0 ){
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
lp.width = mColumnWidth;
holder.itemView.setLayoutParams( lp );
}
holder.bind( activity, column_list.get(position), position , column_list.size() );
}
}

View File

@ -0,0 +1,37 @@
package jp.juggler.subwaytooter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import jp.juggler.subwaytooter.util.LogCategory;
class TabletColumnViewHolder extends RecyclerView.ViewHolder{
static final LogCategory log = new LogCategory( "TabletColumnViewHolder" );
ColumnViewHolder vh;
private int old_position;
TabletColumnViewHolder( View v ){
super( v );
v.findViewById( R.id.vTabletDivider ).setVisibility( View.VISIBLE );
}
void bind( ActMain activity, Column column,int position,int column_count ){
if( vh != null ){
log.d("destroy #%s",old_position);
vh.onPageDestroy( itemView );
vh = null;
}
old_position = position;
log.d("create #%s",position);
vh =new ColumnViewHolder( activity, column);
vh.onPageCreate( itemView,position,column_count );
if( ! column.bFirstInitialized ){
column.startLoading();
}
}
}

View File

@ -9,7 +9,7 @@ import jp.juggler.subwaytooter.table.AcctColor;
public class MyClickableSpan extends ClickableSpan {
public interface LinkClickCallback {
void onClickLink( LinkClickContext account, String url );
void onClickLink( View widget,LinkClickContext account, String url );
}
public static LinkClickCallback link_callback;
@ -30,7 +30,7 @@ public class MyClickableSpan extends ClickableSpan {
@Override public void onClick( View widget ){
if( link_callback != null ){
link_callback.onClickLink( this.account, url );
link_callback.onClickLink( widget,this.account, url );
}
}

View File

@ -0,0 +1,174 @@
package jp.juggler.subwaytooter.view;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSnapHelper;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.View;
/**
* Created by tateisu on 2017/05/12.
*/
public class GravitySnapHelper extends LinearSnapHelper {
private OrientationHelper verticalHelper;
private OrientationHelper horizontalHelper;
private int gravity;
private boolean isRTL;
@SuppressLint("RtlHardcoded")
public GravitySnapHelper(int gravity) {
this.gravity = gravity;
if (this.gravity == Gravity.LEFT) {
this.gravity = Gravity.START;
} else if (this.gravity == Gravity.RIGHT) {
this.gravity = Gravity.END;
}
}
@Override
public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
throws IllegalStateException {
if (recyclerView != null) {
isRTL = ViewCompat.getLayoutDirection(recyclerView) == ViewCompat.LAYOUT_DIRECTION_RTL;
}
super.attachToRecyclerView(recyclerView);
}
@Override
public int[] calculateDistanceToFinalSnap(
@NonNull RecyclerView.LayoutManager layoutManager
,@NonNull View targetView
) {
int[] out = new int[2];
if (layoutManager.canScrollHorizontally()) {
if (gravity == Gravity.START) {
out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
} else { // END
out[0] = distanceToEnd(targetView, getHorizontalHelper(layoutManager));
}
} else {
out[0] = 0;
}
if (layoutManager.canScrollVertically()) {
if (gravity == Gravity.TOP) {
out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager));
} else { // BOTTOM
out[1] = distanceToEnd(targetView, getVerticalHelper(layoutManager));
}
} else {
out[1] = 0;
}
return out;
}
@Override
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
if (layoutManager instanceof LinearLayoutManager ) {
switch (gravity) {
case Gravity.START:
return findStartView(layoutManager, getHorizontalHelper(layoutManager));
case Gravity.TOP:
return findStartView(layoutManager, getVerticalHelper(layoutManager));
case Gravity.END:
return findEndView(layoutManager, getHorizontalHelper(layoutManager));
case Gravity.BOTTOM:
return findEndView(layoutManager, getVerticalHelper(layoutManager));
}
}
return super.findSnapView(layoutManager);
}
private int distanceToStart(View targetView, OrientationHelper helper) {
if ( isRTL ) {
return distanceToEnd(targetView, helper);
}
return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
}
private int distanceToEnd(View targetView, OrientationHelper helper) {
if ( isRTL ) {
return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
}
return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding();
}
private View findStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
if (helper.getDecoratedEnd(child) >= helper.getDecoratedMeasurement(child) / 2
&& helper.getDecoratedEnd(child) > 0) {
return child;
} else {
if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1) {
return null;
} else {
return layoutManager.findViewByPosition(firstChild + 1);
}
}
}
return super.findSnapView(layoutManager);
}
private View findEndView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
if (helper.getDecoratedStart(child) + helper.getDecoratedMeasurement(child) / 2
<= helper.getTotalSpace()) {
return child;
} else {
if (((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition()
== 0) {
return null;
} else {
return layoutManager.findViewByPosition(lastChild - 1);
}
}
}
return super.findSnapView(layoutManager);
}
private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager) {
if (verticalHelper == null) {
verticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
}
return verticalHelper;
}
private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
if (horizontalHelper == null) {
horizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
}
return horizontalHelper;
}
}

View File

@ -0,0 +1,81 @@
package jp.juggler.subwaytooter.view;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
public class MyRecyclerView extends RecyclerView {
public MyRecyclerView( Context context ){
super( context );
init(context);
}
public MyRecyclerView( Context context, @Nullable AttributeSet attrs ){
super( context, attrs );
init(context);
}
public MyRecyclerView( Context context, @Nullable AttributeSet attrs, int defStyle ){
super( context, attrs, defStyle );
init(context);
}
private void init( Context context ){
final ViewConfiguration vc = ViewConfiguration.get(context);
mTouchSlop = vc.getScaledTouchSlop();
}
boolean mForbidStartDragging;
int mScrollPointerId;
int mInitialTouchX;
int mInitialTouchY;
int mTouchSlop;
@Override
public boolean onInterceptTouchEvent( MotionEvent e ){
final int action = MotionEventCompat.getActionMasked( e );
// final int actionIndex = MotionEventCompat.getActionIndex( e );
switch( action ){
case MotionEvent.ACTION_DOWN:
mForbidStartDragging = false;
mScrollPointerId = e.getPointerId(0);
mInitialTouchX = (int) (e.getX() + 0.5f);
mInitialTouchY = (int) (e.getY() + 0.5f);
break;
case MotionEvent.ACTION_MOVE:
final int index = e.findPointerIndex( mScrollPointerId );
if( index >= 0 ){
if( mForbidStartDragging ) return false;
final int x = (int) ( e.getX( index ) + 0.5f );
final int y = (int) ( e.getY( index ) + 0.5f );
boolean canScrollHorizontally = getLayoutManager().canScrollHorizontally();
boolean canScrollVertically = getLayoutManager().canScrollVertically();
final int dx = x - mInitialTouchX;
final int dy = y - mInitialTouchY;
if( ( ! canScrollVertically && Math.abs( dy ) > mTouchSlop )
|| ( ! canScrollHorizontally && Math.abs( dx ) > mTouchSlop )
){
mForbidStartDragging = true;
return false;
}
}
break;
}
return super.onInterceptTouchEvent( e );
}
}

View File

@ -0,0 +1,50 @@
//package jp.juggler.subwaytooter.view;
//
//import android.content.Context;
//import android.content.res.TypedArray;
//import android.graphics.Canvas;
//import android.graphics.Paint;
//import android.graphics.Rect;
//import android.support.v7.widget.RecyclerView;
//import android.view.View;
//
//import jp.juggler.subwaytooter.R;
//import jp.juggler.subwaytooter.Styler;
//
//public class TabletColumnDivider extends RecyclerView.ItemDecoration {
//
// final Paint paint = new Paint();
// int width;
//
// public TabletColumnDivider(Context context) {
//
// width = (int)(0.5f + 1f * context.getResources().getDisplayMetrics().density);
// int color = Styler.getAttributeColor(context, R.attr.colorSettingDivider);
//
// paint.setColor( color );
// }
//
// @Override public void onDraw( Canvas c, RecyclerView parent, RecyclerView.State state) {
// drawDivider(c, parent);
// }
//
// void drawDivider(Canvas c, RecyclerView parent) {
// final int t = parent.getPaddingTop();
// final int b = parent.getHeight() - parent.getPaddingBottom();
//
// final int childCount = parent.getChildCount();
// for (int i = 0; i < childCount; i++) {
// final View child = parent.getChildAt(i);
// final int r = child.getRight();
// final int l = r - width;
// c.drawRect( l,t,r,b,paint );
//
// }
// }
//
// @Override
// public void getItemOffsets( Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
// outRect.set(width,0,width,0);
// }
//
//}

View File

@ -46,6 +46,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<jp.juggler.subwaytooter.view.MyRecyclerView
android:id="@+id/rvPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<LinearLayout

View File

@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<FrameLayout
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"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -117,8 +122,8 @@
android:id="@+id/llColumnSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:maxHeight="240dp"
android:fadeScrollbars="false"
app:maxHeight="240dp"
>
<LinearLayout
@ -173,12 +178,14 @@
android:layout_height="wrap_content"
android:text="@string/dont_refresh_on_activity_resume"
/>
<CheckBox
android:id="@+id/cbHideMediaDefault"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hide_media_default"
/>
<LinearLayout
android:id="@+id/llRegexFilter"
android:layout_width="match_parent"
@ -318,4 +325,14 @@
</com.omadahealth.github.swipyrefreshlayout.library.SwipyRefreshLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/vTabletDivider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="?attr/colorSettingDivider"
android:visibility="gone"
/>
</FrameLayout>