started to implement new search bar

improving new card ui
This commit is contained in:
Mariotaku Lee 2015-01-06 23:46:07 +08:00
parent d7058741b0
commit deae5ed743
171 changed files with 4912 additions and 3077 deletions

View File

@ -1,4 +1,9 @@
include ':twidere', ':twidere.wear', ':twidere.donate.nyanwp', ':twidere.nyan', ':twidere.donate.nyanwp.wear'
include ':twidere'
include ':twidere.wear'
include ':twidere.donate.nyanwp'
include ':twidere.donate.nyanwp.wear'
include ':twidere.component.nyan'
include ':twidere.component.viewer.media'
include ':SlidingMenu', ':DragSortListView', ':MenuComponent', ':RefreshNow', ':PullToRefresh', ':MessageBubbleView'
project(':SlidingMenu').projectDir = file('libraries/SlidingMenu/library')

View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,43 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:support-v4:21.0.3'
compile fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/mariotaku/Tools/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,32 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.viewer.imageviewer;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,30 @@
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mariotaku.twidere.viewer.media">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:allowBackup="true"/>
</manifest>

View File

@ -0,0 +1,39 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.tileimageview.decoder;
import android.graphics.BitmapRegionDecoder;
import com.qozix.tileview.TileView;
import com.qozix.tileview.graphics.BitmapDecoder;
/**
* Created by mariotaku on 15/1/5.
*/
public abstract class AbsTileDecoder implements BitmapDecoder {
public abstract void attachToTileView(TileView tileView);
public abstract boolean isRecycled();
public abstract boolean isSameDecoder(BitmapRegionDecoder decoder);
public abstract void recycle();
}

View File

@ -0,0 +1,188 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.tileimageview.decoder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import com.qozix.tileview.TileView;
import com.qozix.tileview.graphics.BitmapDecoder;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Display an image with {@link com.qozix.tileview.TileView} using {@link android.graphics.BitmapRegionDecoder} <br/>
* <br/>
* <b>Usage:</b> <blockquote> BitmapRegionTileDecoder decoder = new
* BitmapRegionTileDecoder("/path/to/image.jpg", true); <br/>
* decoder.attachToTileView(tileView); </blockquote>
*
* @author mariotaku
*/
@SuppressWarnings("unused")
public final class BitmapRegionTileDecoder extends AbsTileDecoder {
private static final Pattern PATTERN_TILE_FORMAT = Pattern.compile("(\\d+):(\\d+)\\-(\\d+)",
Pattern.CASE_INSENSITIVE);
private final BitmapRegionDecoder mDecoder;
private final int mTileSize;
private final DownSampleDecoder mDownSampleDecoder;
public BitmapRegionTileDecoder(final BitmapRegionDecoder decoder) {
this(decoder, 128, 512);
}
/**
* @param decoder {@link android.graphics.BitmapRegionDecoder} instance
* @param tileSize size of each tile
* @param maxDownSampleSize max size of downsample image
*/
public BitmapRegionTileDecoder(final BitmapRegionDecoder decoder, final int tileSize, final int maxDownSampleSize) {
if (decoder == null) throw new NullPointerException();
mDecoder = decoder;
mTileSize = tileSize;
final int downsampleInSampleSize = nextPowerOfTwo(Math.max(1, Math.max(getWidth(), getHeight())
/ maxDownSampleSize));
mDownSampleDecoder = new DownSampleDecoder(decoder, downsampleInSampleSize);
}
public BitmapRegionTileDecoder(final FileDescriptor fd, final boolean isShareable) throws IOException {
this(BitmapRegionDecoder.newInstance(fd, isShareable));
}
public BitmapRegionTileDecoder(final InputStream is, final boolean isShareable) throws IOException {
this(BitmapRegionDecoder.newInstance(is, isShareable));
}
public BitmapRegionTileDecoder(final String pathName, final boolean isShareable) throws IOException {
this(BitmapRegionDecoder.newInstance(pathName, isShareable));
}
@Override
public void attachToTileView(final TileView tileView) {
tileView.resetDetailLevels();
tileView.setTileDecoder(this);
tileView.setDownsampleDecoder(getDownSampleDecoder());
final int width = getWidth(), height = getHeight(), tileSize = getTileSize();
tileView.setSize(width, height);
for (int i = 0, j = Math.max(width, height) / tileSize; i < j; i++) {
final int s = i + 1;
if (isPowerOfTwo(s)) {
tileView.addDetailLevel(1f / s, BitmapRegionTileDecoder.getDecodeName(s), "sample", tileSize, tileSize);
}
}
}
@Override
public Bitmap decode(final String fileName, final Context context) {
final Matcher m = PATTERN_TILE_FORMAT.matcher(fileName);
if (!m.matches()) return null;
final int inSampleSize = Integer.parseInt(m.group(1));
final int col = Integer.parseInt(m.group(2)), row = Integer.parseInt(m.group(3));
final int tileSize = inSampleSize * mTileSize;
final int left = col * tileSize, top = row * tileSize;
final int right = Math.min(left + tileSize, getWidth());
final int bottom = Math.min(top + tileSize, getHeight());
final Rect rect = new Rect(left, top, right, bottom);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = inSampleSize;
return mDecoder.decodeRegion(rect, options);
}
public BitmapDecoder getDownSampleDecoder() {
return mDownSampleDecoder;
}
public int getHeight() {
return mDecoder.getHeight();
}
public int getTileSize() {
return mTileSize;
}
public int getWidth() {
return mDecoder.getWidth();
}
@Override
public boolean isRecycled() {
return mDecoder.isRecycled();
}
@Override
public void recycle() {
mDecoder.recycle();
}
public boolean isSameDecoder(final BitmapRegionDecoder decoder) {
return mDecoder.equals(decoder);
}
public static String getDecodeName(final int inSampleSize) {
return String.format("%d:%s-%s", inSampleSize, "%col%", "%row%");
}
private static boolean isPowerOfTwo(final int n) {
return n != 0 && (n & n - 1) == 0;
}
private static int nextPowerOfTwo(final int i) {
int n = i;
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;
return n;
}
private static final class DownSampleDecoder implements BitmapDecoder {
private final BitmapRegionDecoder mDecoder;
private final int mInSampleSize;
private DownSampleDecoder(final BitmapRegionDecoder decoder, final int inSampleSize) {
mDecoder = decoder;
mInSampleSize = inSampleSize;
}
@Override
public Bitmap decode(final String fileName, final Context context) {
final Rect rect = new Rect(0, 0, mDecoder.getWidth(), mDecoder.getHeight());
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = mInSampleSize;
return mDecoder.decodeRegion(rect, options);
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.tileimageview.decoder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapRegionDecoder;
import com.qozix.tileview.TileView;
public final class DummyTileDecoder extends AbsTileDecoder {
private final Bitmap mFallback;
public DummyTileDecoder(Bitmap fallback) {
mFallback = fallback;
}
@Override
public void attachToTileView(final TileView tileView) {
tileView.setTileDecoder(this);
tileView.setDownsampleDecoder(this);
tileView.resetDetailLevels();
if (mFallback != null) {
final int width = mFallback.getWidth(), height = mFallback.getHeight();
tileView.setSize(width, height);
tileView.addDetailLevel(1, "", "sample", width, height);
} else {
tileView.setSize(0, 0);
}
}
@Override
public Bitmap decode(final String fileName, final Context context) {
return null;
}
@Override
public boolean isRecycled() {
return mFallback != null && mFallback.isRecycled();
}
@Override
public boolean isSameDecoder(BitmapRegionDecoder decoder) {
return false;
}
@Override
public void recycle() {
if (mFallback != null) {
mFallback.recycle();
}
}
}

View File

@ -0,0 +1,282 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.tileimageview.widget;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Point;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.qozix.layouts.ZoomPanLayout.GestureListener;
import com.qozix.layouts.ZoomPanLayout.ZoomPanListener;
import com.qozix.tileview.TileView;
import com.qozix.tileview.TileView.TileViewEventListener;
import com.qozix.tileview.hotspots.HotSpot;
import com.qozix.tileview.hotspots.HotSpotEventListener;
import com.qozix.tileview.markers.MarkerEventListener;
import org.mariotaku.tileimageview.decoder.AbsTileDecoder;
import org.mariotaku.tileimageview.decoder.BitmapRegionTileDecoder;
import org.mariotaku.tileimageview.decoder.DummyTileDecoder;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("unused")
public final class TileImageView extends FrameLayout {
private final TileView mTileView;
private AbsTileDecoder mTileDecoder;
public TileImageView(final Context context) {
this(context, null);
}
public TileImageView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public TileImageView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
mTileView = new TileView(context);
super.addView(mTileView, 0, generateDefaultLayoutParams());
}
public View addCallout(final View view, final double x, final double y) {
return mTileView.addCallout(view, x, y);
}
public View addCallout(final View view, final double x, final double y, final float anchorX, final float anchorY) {
return mTileView.addCallout(view, x, y, anchorX, anchorY);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void addChildrenForAccessibility(@NonNull final ArrayList<View> childrenForAccessibility) {
mTileView.addChildrenForAccessibility(childrenForAccessibility);
}
@Override
public void addFocusables(final ArrayList<View> views, final int direction) {
mTileView.addFocusables(views, direction);
}
@Override
public void addFocusables(@NonNull final ArrayList<View> views, final int direction, final int focusableMode) {
mTileView.addFocusables(views, direction, focusableMode);
}
public boolean addGestureListener(final GestureListener listener) {
return mTileView.addGestureListener(listener);
}
public HotSpot addHotSpot(final HotSpot hotSpot) {
return mTileView.addHotSpot(hotSpot);
}
public HotSpot addHotSpot(final List<double[]> positions) {
return mTileView.addHotSpot(positions);
}
public HotSpot addHotSpot(final List<double[]> positions, final HotSpotEventListener listener) {
return mTileView.addHotSpot(positions, listener);
}
public void addHotSpotEventListener(final HotSpotEventListener listener) {
mTileView.addHotSpotEventListener(listener);
}
public View addMarker(final View view, final double x, final double y) {
return mTileView.addMarker(view, x, y);
}
public View addMarker(final View view, final double x, final double y, final float anchorX, final float anchorY) {
return mTileView.addMarker(view, x, y, anchorX, anchorY);
}
public void addMarkerEventListener(final MarkerEventListener listener) {
mTileView.addMarkerEventListener(listener);
}
public void addTileViewEventListener(final TileViewEventListener listener) {
mTileView.addTileViewEventListener(listener);
}
@Override
public void addView(@NonNull final View child) {
throw new UnsupportedOperationException();
}
@Override
public void addView(@NonNull final View child, final int index) {
throw new UnsupportedOperationException();
}
@Override
public void addView(@NonNull final View child, final int width, final int height) {
throw new UnsupportedOperationException();
}
@Override
public void addView(@NonNull final View child, final int index, final ViewGroup.LayoutParams params) {
throw new UnsupportedOperationException();
}
@Override
public void addView(@NonNull final View child, final ViewGroup.LayoutParams params) {
throw new UnsupportedOperationException();
}
public boolean addZoomPanListener(final ZoomPanListener listener) {
return mTileView.addZoomPanListener(listener);
}
public void cancelRender() {
mTileView.cancelRender();
}
@Override
public boolean canScrollHorizontally(final int direction) {
final double scaledBoundaryX = mTileView.getScaledWidth();
final int scrollX = mTileView.getScrollX();
return scrollX + direction > 0 && scrollX + mTileView.getWidth() + direction < scaledBoundaryX;
}
@Override
public boolean canScrollVertically(final int direction) {
final double scaledBoundaryY = mTileView.getScaledHeight();
final int scrollY = mTileView.getScrollY();
return scrollY + direction > 0 && scrollY + mTileView.getHeight() + direction < scaledBoundaryY;
}
@Override
public boolean dispatchTouchEvent(@NonNull final MotionEvent ev) {
return mTileView.dispatchTouchEvent(ev);
}
public int getBaseHeight() {
return mTileView.getBaseHeight();
}
public int getBaseWidth() {
return mTileView.getBaseWidth();
}
public Point getCenter() {
return new Point(mTileView.getScrollX(), mTileView.getScrollY());
}
public double getScale() {
return mTileView.getScale();
}
public boolean removeGestureListener(final GestureListener listener) {
return mTileView.removeGestureListener(listener);
}
public void removeHotSpot(final HotSpot hotSpot) {
mTileView.removeHotSpot(hotSpot);
}
public void removeHotSpotEventListener(final HotSpotEventListener listener) {
mTileView.removeHotSpotEventListener(listener);
}
public void removeMarkerEventListener(final MarkerEventListener listener) {
mTileView.removeMarkerEventListener(listener);
}
public void requestRender() {
mTileView.requestRender();
}
public void resume() {
mTileView.resume();
}
public void scrollToAndCenter(final Point point) {
mTileView.scrollToAndCenter(point);
}
public void scrollToPoint(final Point point) {
mTileView.scrollToPoint(point);
}
public void setBitmapRegionDecoder(final BitmapRegionDecoder decoder, final Bitmap fallback) {
if (mTileDecoder != null && mTileDecoder.isSameDecoder(decoder)) return;
if (mTileDecoder != null) {
mTileDecoder.recycle();
mTileDecoder = null;
}
if (decoder == null) {
mTileDecoder = new DummyTileDecoder(fallback);
} else {
mTileDecoder = new BitmapRegionTileDecoder(decoder);
}
mTileDecoder.attachToTileView(mTileView);
}
public void setDragStartThreshold(final int threshold) {
mTileView.setDragStartThreshold(threshold);
}
public void setScale(final double d) {
mTileView.setScale(d);
}
public void setScaleLimits(final double min, final double max) {
mTileView.setScaleLimits(min, max);
}
public void setScaleToFit(final boolean shouldScaleToFit) {
mTileView.setScaleToFit(shouldScaleToFit);
}
public void slideToAndCenter(final double x, final double y) {
mTileView.slideToAndCenter(x, y);
}
public void slideToAndCenter(final Point point) {
mTileView.slideToAndCenter(point);
}
public void slideToPoint(final Point point) {
mTileView.slideToPoint(point);
}
public void smoothScaleTo(final double destination, final int duration) {
mTileView.smoothScaleTo(destination, duration);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER);
}
}

View File

@ -17,15 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter;
package org.mariotaku.twidere.viewer.media;
import android.content.Context;
import android.app.Activity;
import android.support.v4.app.FragmentActivity;
/**
* Created by mariotaku on 15/1/3.
* Created by mariotaku on 15/1/5.
*/
public class ParcelableActivitiesAboutMeAdapter extends ParcelableActivitiesAdapter {
protected ParcelableActivitiesAboutMeAdapter(Context context) {
super(context);
}
public class MediaViewerActivity extends FragmentActivity {
}

View File

@ -0,0 +1,21 @@
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
</resources>

View File

@ -74,7 +74,7 @@ android {
}
dependencies {
compile project(':twidere.nyan')
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:1.1.0'
compile project(':twidere.component.nyan')
compile fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -74,6 +74,6 @@ android {
dependencies {
wearApp project(':twidere.donate.nyanwp.wear')
compile project(':twidere.nyan')
compile project(':twidere.component.nyan')
compile fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -104,11 +104,12 @@ dependencies {
googleCompile 'com.google.android.gms:play-services:6.5.87'
fdroidCompile 'org.osmdroid:osmdroid-android:4.2'
fdroidCompile 'org.slf4j:slf4j-simple:1.7.9'
compile project(':twidere.component.nyan')
compile project(':twidere.component.viewer.media')
compile project(':SlidingMenu')
compile project(':DragSortListView')
compile project(':MenuComponent')
compile project(':MessageBubbleView')
compile project(':twidere.nyan')
compile fileTree(dir: 'libs/main', include: ['*.jar'])
googleCompile fileTree(dir: 'libs/google', include: ['*.jar'])
}

View File

@ -169,6 +169,17 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.support.HomeActivity"/>
</activity>
<activity
android:name=".activity.support.GlobalSearchBoxActivity"
android:launchMode="singleTop"
android:theme="@style/Theme.Blank.Dialog"
android:windowSoftInputMode="adjustResize"
android:label="@android:string/search_go">
<intent-filter>
<action android:name="org.mariotaku.twidere.GLOBAL_SEARCH"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".activity.support.SignInActivity"
android:label="@string/sign_in"
@ -373,12 +384,11 @@
android:value=".activity.support.HomeActivity"/>
</activity>
<activity
android:name="org.mariotaku.gallery3d.ImageViewerGLActivity"
android:name=".activity.support.MediaViewerActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:hardwareAccelerated="true"
android:label="@string/view_image"
android:launchMode="singleTop"
android:process=":image_viewer"
android:theme="@style/Theme.Blank">
<intent-filter>
<action android:name="org.mariotaku.twidere.VIEW_IMAGE"/>

View File

@ -1,17 +1,20 @@
/*
* Copyright (C) 2009 The Android Open Source Project
* Twidere - Twitter client for Android
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* http://www.apache.org/licenses/LICENSE-2.0
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.gallery3d;
@ -49,14 +52,15 @@ import org.mariotaku.menucomponent.widget.MenuBar.MenuBarListener;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.loader.support.TileImageLoader;
import org.mariotaku.twidere.util.SaveImageTask;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import java.io.File;
public final class ImageViewerGLActivity extends BaseSupportActivity implements Constants, PhotoView.Listener,
GLImageLoader.DownloadListener, LoaderManager.LoaderCallbacks<GLImageLoader.Result>, OnMenuVisibilityListener,
public final class ImageViewerGLActivityOld extends BaseSupportActivity implements Constants, PhotoView.Listener,
TileImageLoader.DownloadListener, LoaderManager.LoaderCallbacks<TileImageLoader.Result>, OnMenuVisibilityListener,
MenuBarListener {
private final GLView mRootPane = new GLView() {
@ -139,13 +143,13 @@ public final class ImageViewerGLActivity extends BaseSupportActivity implements
}
@Override
public Loader<GLImageLoader.Result> onCreateLoader(final int id, final Bundle args) {
public Loader<TileImageLoader.Result> onCreateLoader(final int id, final Bundle args) {
mProgress.setVisibility(View.VISIBLE);
mProgress.setIndeterminate(true);
invalidateOptionsMenu();
final Uri uri = args.getParcelable(EXTRA_URI);
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
return new GLImageLoader(this, this, accountId, uri);
return new TileImageLoader(this, this, accountId, uri);
}
@Override
@ -178,12 +182,12 @@ public final class ImageViewerGLActivity extends BaseSupportActivity implements
@Override
public void onLoaderReset(final Loader<GLImageLoader.Result> loader) {
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
}
@Override
public void onLoadFinished(final Loader<GLImageLoader.Result> loader, final GLImageLoader.Result data) {
public void onLoadFinished(final Loader<TileImageLoader.Result> loader, final TileImageLoader.Result data) {
if (data != null && (data.decoder != null || data.bitmap != null)) {
if (data.decoder != null) {
mGLRootView.setVisibility(View.VISIBLE);
@ -525,9 +529,9 @@ public final class ImageViewerGLActivity extends BaseSupportActivity implements
}
private static class MyHandler extends SynchronizedHandler {
ImageViewerGLActivity activity;
ImageViewerGLActivityOld activity;
private MyHandler(final ImageViewerGLActivity activity) {
private MyHandler(final ImageViewerGLActivityOld activity) {
super(activity.getGLRoot());
this.activity = activity;
}

View File

@ -18,7 +18,7 @@ package org.mariotaku.gallery3d.ui;
import android.util.Log;
import org.mariotaku.gallery3d.util.GalleryUtils;
import org.mariotaku.twidere.util.MathUtils;
import java.util.WeakHashMap;
@ -153,8 +153,8 @@ abstract class BasicTexture implements Texture {
protected void setSize(final int width, final int height) {
mWidth = width;
mHeight = height;
mTextureWidth = GalleryUtils.nextPowerOf2(width);
mTextureHeight = GalleryUtils.nextPowerOf2(height);
mTextureWidth = MathUtils.nextPowerOf2(width);
mTextureHeight = MathUtils.nextPowerOf2(height);
if (mTextureWidth > MAX_TEXTURE_SIZE || mTextureHeight > MAX_TEXTURE_SIZE) {
Log.w(TAG, String.format("texture is too large: %d x %d", mTextureWidth, mTextureHeight), new Exception());
}

File diff suppressed because it is too large Load Diff

View File

@ -110,30 +110,7 @@ public class GalleryUtils {
return color >>> 24 == 0xFF;
}
// Returns the next power of two.
// Returns the input if it is already power of 2.
// Throws IllegalArgumentException if the input is <= 0 or
// the answer overflows.
public static int nextPowerOf2(int n) {
if (n <= 0 || n > 1 << 30) throw new IllegalArgumentException("n is invalid: " + n);
n -= 1;
n |= n >> 16;
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n + 1;
}
// Returns the previous power of two.
// Returns the input if it is already power of 2.
// Throws IllegalArgumentException if the input is <= 0
public static int prevPowerOf2(final int n) {
if (n <= 0) throw new IllegalArgumentException();
return Integer.highestOneBit(n);
}
public static void waitWithoutInterrupt(final Object object) {
public static void waitWithoutInterrupt(final Object object) {
try {
object.wait();
} catch (final InterruptedException e) {

View File

@ -53,7 +53,7 @@ import org.mariotaku.twidere.activity.support.DataImportActivity;
import org.mariotaku.twidere.graphic.EmptyDrawable;
import org.mariotaku.twidere.util.CompareUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.holder.ListViewHolder;
import org.mariotaku.twidere.view.holder.ViewListHolder;
import java.util.ArrayList;
import java.util.List;
@ -427,7 +427,7 @@ public class SettingsActivity extends BasePreferenceActivity {
}
private static class HeaderViewHolder extends ListViewHolder {
private static class HeaderViewHolder extends ViewListHolder {
private final TextView title, summary;
private final ImageView icon;
private final LinearLayout content;

View File

@ -38,7 +38,7 @@ import org.mariotaku.twidere.view.MainFrameLayout.FitSystemWindowsCallback;
import java.util.ArrayList;
@SuppressLint("Registered")
public class BaseSupportActivity extends BaseSupportThemedActivity implements Constants,
public class BaseSupportActivity extends ThemedFragmentActivity implements Constants,
FitSystemWindowsCallback, SystemWindowsInsetsCallback, IControlBarActivity {
private boolean mInstanceStateSaved, mIsVisible, mIsOnTop;

View File

@ -28,7 +28,7 @@ import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.ThemeUtils;
@SuppressLint("Registered")
public class BaseSupportDialogActivity extends BaseSupportThemedActivity implements Constants, IThemedActivity {
public class BaseSupportDialogActivity extends ThemedFragmentActivity implements Constants, IThemedActivity {
private boolean mInstanceStateSaved;

View File

@ -0,0 +1,85 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity.support;
import android.content.Intent;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Spinner;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.util.ThemeUtils;
import java.util.List;
/**
* Created by mariotaku on 15/1/6.
*/
public class GlobalSearchBoxActivity extends BaseSupportActivity {
private Spinner mAccountSpinner;
@Override
public int getThemeResourceId() {
return ThemeUtils.getGlobalSearchThemeResource(this);
}
@Override
public void onContentChanged() {
super.onContentChanged();
mAccountSpinner = (Spinner) findViewById(R.id.account_spinner);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_global_search_box);
final List<ParcelableAccount> accounts = ParcelableAccount.getAccountsList(this, false);
final AccountsSpinnerAdapter accountsSpinnerAdapter = new AccountsSpinnerAdapter(this, R.layout.spinner_item_account_icon);
accountsSpinnerAdapter.setDropDownViewResource(R.layout.list_item_user);
accountsSpinnerAdapter.addAll(accounts);
mAccountSpinner.setAdapter(accountsSpinnerAdapter);
if (savedInstanceState == null) {
final Intent intent = getIntent();
final int index = accountsSpinnerAdapter.findItemPosition(intent.getLongExtra(EXTRA_ACCOUNT_ID, -1));
if (index != -1) {
mAccountSpinner.setSelection(index);
}
}
}
@Override
protected void onResume() {
super.onResume();
updateWindowAttributes();
}
private void updateWindowAttributes() {
final Window window = getWindow();
final WindowManager.LayoutParams attributes = window.getAttributes();
attributes.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
window.setAttributes(attributes);
}
}

View File

@ -35,7 +35,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class ImagePickerActivity extends BaseSupportThemedActivity {
public class ImagePickerActivity extends ThemedFragmentActivity {
public static final int REQUEST_PICK_IMAGE = 101;
public static final int REQUEST_TAKE_PHOTO = 102;

View File

@ -0,0 +1,347 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mariotaku.twidere.activity.support;
import android.app.ActionBar;
import android.app.ActionBar.OnMenuVisibilityListener;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.widget.ImageView;
import android.widget.ProgressBar;
import org.mariotaku.menucomponent.widget.MenuBar;
import org.mariotaku.menucomponent.widget.MenuBar.MenuBarListener;
import org.mariotaku.tileimageview.widget.TileImageView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.loader.support.TileImageLoader;
import org.mariotaku.twidere.util.SaveImageTask;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import java.io.File;
public final class MediaViewerActivity extends BaseSupportActivity implements Constants,
TileImageLoader.DownloadListener, LoaderManager.LoaderCallbacks<TileImageLoader.Result>,
OnMenuVisibilityListener, MenuBarListener {
private ActionBar mActionBar;
private ProgressBar mProgress;
private ImageView mImageView;
private MenuBar mMenuBar;
private long mContentLength;
private File mImageFile;
private boolean mLoaderInitialized;
@Override
public int getThemeResourceId() {
return ThemeUtils.getViewerThemeResource(this);
}
@Override
public void onContentChanged() {
super.onContentChanged();
mImageView = (ImageView) findViewById(R.id.image_viewer);
mProgress = (ProgressBar) findViewById(R.id.progress);
mMenuBar = (MenuBar) findViewById(R.id.menu_bar);
}
@Override
public Loader<TileImageLoader.Result> onCreateLoader(final int id, final Bundle args) {
mProgress.setVisibility(View.VISIBLE);
mProgress.setIndeterminate(true);
invalidateOptionsMenu();
final Uri uri = args.getParcelable(EXTRA_URI);
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
return new TileImageLoader(this, this, accountId, uri);
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_image_viewer_action_bar, menu);
return true;
}
@Override
public void onDownloadError(final Throwable t) {
mContentLength = 0;
}
@Override
public void onDownloadFinished() {
mContentLength = 0;
}
@Override
public void onDownloadStart(final long total) {
mContentLength = total;
mProgress.setIndeterminate(total <= 0);
mProgress.setMax(total > 0 ? (int) (total / 1024) : 0);
}
@Override
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
}
@Override
public void onLoadFinished(final Loader<TileImageLoader.Result> loader, final TileImageLoader.Result data) {
if (data.hasData()) {
mImageView.setVisibility(View.VISIBLE);
// mImageView.setBitmapRegionDecoder(data.decoder, data.bitmap);
// mImageView.setScale(1);
mImageView.setImageBitmap(data.bitmap);
mImageFile = data.file;
} else {
mImageView.setVisibility(View.GONE);
mImageFile = null;
Utils.showErrorMessage(this, null, data.exception, true);
}
mProgress.setVisibility(View.GONE);
mProgress.setProgress(0);
invalidateOptionsMenu();
updateShareIntent();
}
@Override
public boolean onMenuItemClick(final MenuItem item) {
switch (item.getItemId()) {
case MENU_SAVE: {
if (mImageFile != null) {
new SaveImageTask(this, mImageFile).execute();
}
break;
}
case MENU_OPEN_IN_BROWSER: {
final Intent intent = getIntent();
intent.setExtrasClassLoader(getClassLoader());
final Uri uri = intent.getData();
final Uri orig = intent.getParcelableExtra(EXTRA_URI_ORIG);
final Uri uriPreferred = orig != null ? orig : uri;
if (uriPreferred == null) return false;
final String scheme = uriPreferred.getScheme();
if ("http".equals(scheme) || "https".equals(scheme)) {
final Intent open_intent = new Intent(Intent.ACTION_VIEW, uriPreferred);
open_intent.addCategory(Intent.CATEGORY_BROWSABLE);
try {
startActivity(open_intent);
} catch (final ActivityNotFoundException e) {
// Ignore.
}
}
break;
}
default: {
final Intent intent = item.getIntent();
if (intent != null) {
try {
startActivity(intent);
} catch (final ActivityNotFoundException e) {
// Ignore.
}
return true;
}
return false;
}
}
return true;
}
@Override
public void onMenuVisibilityChanged(final boolean isVisible) {
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
onBackPressed();
break;
}
case MENU_REFRESH: {
loadImage();
break;
}
}
return true;
}
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
final LoaderManager lm = getSupportLoaderManager();
Utils.setMenuItemAvailability(menu, MENU_REFRESH, !lm.hasRunningLoaders());
return super.onPrepareOptionsMenu(menu);
}
@Override
public void onProgressUpdate(final long downloaded) {
if (mContentLength == 0) {
mProgress.setIndeterminate(true);
return;
}
mProgress.setIndeterminate(false);
mProgress.setProgress((int) (downloaded / 1024));
}
public void showProgress() {
mProgress.setVisibility(View.VISIBLE);
mProgress.setIndeterminate(true);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_viewer);
mActionBar = getActionBar();
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.addOnMenuVisibilityListener(this);
if (savedInstanceState == null) {
loadImage();
}
// mImageView.setScaleToFit(false);
mImageView.addOnLayoutChangeListener(new TileImageViewLayoutListener());
mMenuBar.setMenuBarListener(this);
mMenuBar.inflate(R.menu.menu_image_viewer);
mMenuBar.setIsBottomBar(true);
mMenuBar.show();
}
private static class TileImageViewLayoutListener implements OnLayoutChangeListener {
@Override
public void onLayoutChange(final View v, final int left, final int top, final int right, final int bottom,
final int oldLeft, final int oldTop, final int oldRight, final int oldBottom) {
if (!(v instanceof TileImageView)) return;
final TileImageView tileView = (TileImageView) v;
final int baseWidth = tileView.getBaseWidth(), baseHeight = tileView.getBaseHeight();
final double scaleMin = getMinScale(left, top, right, bottom, baseWidth, baseHeight);
tileView.setScaleLimits(scaleMin, Math.max(scaleMin, 2.0));
final double oldScaleMin = getMinScale(oldLeft, oldTop, oldRight, oldBottom, baseWidth, baseHeight);
final double oldScale = tileView.getScale();
tileView.setScaleLimits(scaleMin, Math.max(scaleMin, 2.0));
if (oldScale == oldScaleMin) {
tileView.setScale(scaleMin);
}
}
private static double getMinScale(final int left, final int top, final int right, final int bottom,
final int baseWidth, final int baseHeight) {
final double viewWidth = right - left, viewHeight = bottom - top;
if (viewWidth <= 0 || viewHeight <= 0) return 0;
final double widthScale = Math.min(1, baseWidth / viewWidth), heightScale = Math.min(1, baseHeight
/ viewHeight);
return Math.min(widthScale, heightScale);
}
}
@Override
protected void onDestroy() {
mActionBar.removeOnMenuVisibilityListener(this);
super.onDestroy();
}
@Override
protected void onNewIntent(final Intent intent) {
setIntent(intent);
loadImage();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
private void loadImage() {
getSupportLoaderManager().destroyLoader(0);
final Intent intent = getIntent();
final Uri uri = intent.getData();
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
if (uri == null) {
finish();
return;
}
final Bundle args = new Bundle();
args.putParcelable(EXTRA_URI, uri);
args.putLong(EXTRA_ACCOUNT_ID, accountId);
if (!mLoaderInitialized) {
getSupportLoaderManager().initLoader(0, args, this);
mLoaderInitialized = true;
} else {
getSupportLoaderManager().restartLoader(0, args, this);
}
}
void updateShareIntent() {
final MenuItem item = mMenuBar.getMenu().findItem(MENU_SHARE);
if (item == null || !item.hasSubMenu()) return;
final SubMenu subMenu = item.getSubMenu();
subMenu.clear();
final Intent intent = getIntent();
final Uri uri = intent.getData();
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
if (mImageFile != null && mImageFile.exists()) {
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(mImageFile));
} else {
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, uri.toString());
}
Utils.addIntentToMenu(this, subMenu, shareIntent);
}
@Override
public void onPreShowMenu(Menu menu) {
}
@Override
public void onPostShowMenu(Menu menu) {
}
}

View File

@ -36,12 +36,16 @@ import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.ShapedImageView;
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle;
import static org.mariotaku.twidere.util.Utils.restartActivity;
public abstract class BaseSupportThemedActivity extends FragmentActivity implements Constants, IThemedActivity {
public abstract class ThemedFragmentActivity extends FragmentActivity implements Constants, IThemedActivity {
private int mCurrentThemeResource, mCurrentThemeColor, mCurrentThemeBackgroundAlpha;
@ShapeStyle
private int mProfileImageStyle;
@Override
public Resources getDefaultResources() {
@ -112,6 +116,10 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
@Override
public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) {
final View view = ThemeUtils.createView(name, context, attrs, mCurrentThemeColor);
if (view instanceof ShapedImageView) {
final ShapedImageView shapedImageView = (ShapedImageView) view;
shapedImageView.setStyle(mProfileImageStyle);
}
if (view != null) return view;
return super.onCreateView(name, context, attrs);
}
@ -129,6 +137,7 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
mCurrentThemeResource = getThemeResourceId();
mCurrentThemeColor = getThemeColor();
mCurrentThemeBackgroundAlpha = getThemeBackgroundAlpha();
mProfileImageStyle = Utils.getProfileImageStyle(this);
ThemeUtils.notifyStatusBarColorChanged(this, mCurrentThemeResource, mCurrentThemeColor,
mCurrentThemeBackgroundAlpha);
setTheme(mCurrentThemeResource);

View File

@ -19,11 +19,6 @@
package org.mariotaku.twidere.activity.support;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.ParseUtils.parseString;
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@ -49,6 +44,9 @@ import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.task.TwidereAsyncTask;
import java.util.ArrayList;
import java.util.List;
import twitter4j.ResponseList;
import twitter4j.Twitter;
import twitter4j.TwitterException;
@ -56,284 +54,286 @@ import twitter4j.User;
import twitter4j.UserList;
import twitter4j.http.HttpResponseCode;
import java.util.ArrayList;
import java.util.List;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.ParseUtils.parseString;
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
public class UserListSelectorActivity extends BaseSupportDialogActivity implements OnClickListener, OnItemClickListener {
private AutoCompleteTextView mEditScreenName;
private ListView mUserListsListView, mUsersListView;
private SimpleParcelableUserListsAdapter mUserListsAdapter;
private SimpleParcelableUsersAdapter mUsersAdapter;
private View mUsersListContainer, mUserListsContainer, mCreateUserListContainer;
private AutoCompleteTextView mEditScreenName;
private ListView mUserListsListView, mUsersListView;
private SimpleParcelableUserListsAdapter mUserListsAdapter;
private SimpleParcelableUsersAdapter mUsersAdapter;
private View mUsersListContainer, mUserListsContainer, mCreateUserListContainer;
private String mScreenName;
private String mScreenName;
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (BROADCAST_USER_LIST_CREATED.equals(action)) {
getUserLists(mScreenName);
}
}
};
@Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (BROADCAST_USER_LIST_CREATED.equals(action)) {
getUserLists(mScreenName);
}
}
};
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.screen_name_confirm: {
final String screen_name = parseString(mEditScreenName.getText());
if (isEmpty(screen_name)) return;
searchUser(screen_name);
break;
}
case R.id.create_list: {
final DialogFragment f = new CreateUserListDialogFragment();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, getAccountId());
f.setArguments(args);
f.show(getSupportFragmentManager(), null);
break;
}
}
}
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.screen_name_confirm: {
final String screen_name = parseString(mEditScreenName.getText());
if (isEmpty(screen_name)) return;
searchUser(screen_name);
break;
}
case R.id.create_list: {
final DialogFragment f = new CreateUserListDialogFragment();
final Bundle args = new Bundle();
args.putLong(EXTRA_ACCOUNT_ID, getAccountId());
f.setArguments(args);
f.show(getSupportFragmentManager(), null);
break;
}
}
}
@Override
public void onContentChanged() {
super.onContentChanged();
mUsersListContainer = findViewById(R.id.users_list_container);
mUserListsContainer = findViewById(R.id.user_lists_container);
mEditScreenName = (AutoCompleteTextView) findViewById(R.id.edit_screen_name);
mUserListsListView = (ListView) findViewById(R.id.user_lists_list);
mUsersListView = (ListView) findViewById(R.id.users_list);
mCreateUserListContainer = findViewById(R.id.create_list_container);
}
@Override
public void onContentChanged() {
super.onContentChanged();
mUsersListContainer = findViewById(R.id.users_list_container);
mUserListsContainer = findViewById(R.id.user_lists_container);
mEditScreenName = (AutoCompleteTextView) findViewById(R.id.edit_screen_name);
mUserListsListView = (ListView) findViewById(R.id.user_lists_list);
mUsersListView = (ListView) findViewById(R.id.users_list);
mCreateUserListContainer = findViewById(R.id.create_list_container);
}
@Override
public void onItemClick(final AdapterView<?> view, final View child, final int position, final long id) {
final int view_id = view.getId();
final ListView list = (ListView) view;
if (view_id == R.id.users_list) {
final ParcelableUser user = mUsersAdapter.getItem(position - list.getHeaderViewsCount());
if (user == null) return;
if (isSelectingUser()) {
final Intent data = new Intent();
data.setExtrasClassLoader(getClassLoader());
data.putExtra(EXTRA_USER, user);
setResult(RESULT_OK, data);
finish();
} else {
getUserLists(user.screen_name);
}
} else if (view_id == R.id.user_lists_list) {
final Intent data = new Intent();
data.putExtra(EXTRA_USER_LIST, mUserListsAdapter.getItem(position - list.getHeaderViewsCount()));
setResult(RESULT_OK, data);
finish();
}
}
@Override
public void onItemClick(final AdapterView<?> view, final View child, final int position, final long id) {
final int view_id = view.getId();
final ListView list = (ListView) view;
if (view_id == R.id.users_list) {
final ParcelableUser user = mUsersAdapter.getItem(position - list.getHeaderViewsCount());
if (user == null) return;
if (isSelectingUser()) {
final Intent data = new Intent();
data.setExtrasClassLoader(getClassLoader());
data.putExtra(EXTRA_USER, user);
setResult(RESULT_OK, data);
finish();
} else {
getUserLists(user.screen_name);
}
} else if (view_id == R.id.user_lists_list) {
final Intent data = new Intent();
data.putExtra(EXTRA_USER_LIST, mUserListsAdapter.getItem(position - list.getHeaderViewsCount()));
setResult(RESULT_OK, data);
finish();
}
}
public void setUsersData(final List<ParcelableUser> data) {
mUsersAdapter.setData(data, true);
mUsersListContainer.setVisibility(View.VISIBLE);
mUserListsContainer.setVisibility(View.GONE);
}
public void setUsersData(final List<ParcelableUser> data) {
mUsersAdapter.setData(data, true);
mUsersListContainer.setVisibility(View.VISIBLE);
mUserListsContainer.setVisibility(View.GONE);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
if (!intent.hasExtra(EXTRA_ACCOUNT_ID)) {
finish();
return;
}
setContentView(R.layout.activity_user_list_selector);
if (savedInstanceState == null) {
mScreenName = intent.getStringExtra(EXTRA_SCREEN_NAME);
} else {
mScreenName = savedInstanceState.getString(EXTRA_SCREEN_NAME);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
if (!intent.hasExtra(EXTRA_ACCOUNT_ID)) {
finish();
return;
}
setContentView(R.layout.activity_user_list_selector);
if (savedInstanceState == null) {
mScreenName = intent.getStringExtra(EXTRA_SCREEN_NAME);
} else {
mScreenName = savedInstanceState.getString(EXTRA_SCREEN_NAME);
}
final boolean selecting_user = isSelectingUser();
setTitle(selecting_user ? R.string.select_user : R.string.select_user_list);
if (!isEmpty(mScreenName)) {
if (selecting_user) {
searchUser(mScreenName);
} else {
getUserLists(mScreenName);
}
}
mEditScreenName.setAdapter(new UserHashtagAutoCompleteAdapter(this));
mEditScreenName.setText(mScreenName);
mUserListsListView.setAdapter(mUserListsAdapter = new SimpleParcelableUserListsAdapter(this));
mUsersListView.setAdapter(mUsersAdapter = new SimpleParcelableUsersAdapter(this));
mUserListsListView.setOnItemClickListener(this);
mUsersListView.setOnItemClickListener(this);
if (selecting_user) {
mUsersListContainer.setVisibility(View.VISIBLE);
mUserListsContainer.setVisibility(View.GONE);
} else {
mUsersListContainer.setVisibility(isEmpty(mScreenName) ? View.VISIBLE : View.GONE);
mUserListsContainer.setVisibility(isEmpty(mScreenName) ? View.GONE : View.VISIBLE);
}
}
final boolean selecting_user = isSelectingUser();
setTitle(selecting_user ? R.string.select_user : R.string.select_user_list);
if (!isEmpty(mScreenName)) {
if (selecting_user) {
searchUser(mScreenName);
} else {
getUserLists(mScreenName);
}
}
mEditScreenName.setAdapter(new UserHashtagAutoCompleteAdapter(this));
mEditScreenName.setText(mScreenName);
mUserListsListView.setAdapter(mUserListsAdapter = new SimpleParcelableUserListsAdapter(this));
mUsersListView.setAdapter(mUsersAdapter = new SimpleParcelableUsersAdapter(this));
mUserListsListView.setOnItemClickListener(this);
mUsersListView.setOnItemClickListener(this);
if (selecting_user) {
mUsersListContainer.setVisibility(View.VISIBLE);
mUserListsContainer.setVisibility(View.GONE);
} else {
mUsersListContainer.setVisibility(isEmpty(mScreenName) ? View.VISIBLE : View.GONE);
mUserListsContainer.setVisibility(isEmpty(mScreenName) ? View.GONE : View.VISIBLE);
}
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_SCREEN_NAME, mScreenName);
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_SCREEN_NAME, mScreenName);
}
@Override
protected void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_USER_LIST_CREATED);
registerReceiver(mStatusReceiver, filter);
}
@Override
protected void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_USER_LIST_CREATED);
registerReceiver(mStatusReceiver, filter);
}
@Override
protected void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
@Override
protected void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
private long getAccountId() {
return getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
}
private long getAccountId() {
return getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
}
private void getUserLists(final String screen_name) {
if (screen_name == null) return;
mScreenName = screen_name;
final GetUserListsTask task = new GetUserListsTask(this, getAccountId(), screen_name);
task.executeTask();
}
private void getUserLists(final String screen_name) {
if (screen_name == null) return;
mScreenName = screen_name;
final GetUserListsTask task = new GetUserListsTask(this, getAccountId(), screen_name);
task.executeTask();
}
private boolean isSelectingUser() {
return INTENT_ACTION_SELECT_USER.equals(getIntent().getAction());
}
private boolean isSelectingUser() {
return INTENT_ACTION_SELECT_USER.equals(getIntent().getAction());
}
private void searchUser(final String name) {
final SearchUsersTask task = new SearchUsersTask(this, getAccountId(), name);
task.executeTask();
}
private void searchUser(final String name) {
final SearchUsersTask task = new SearchUsersTask(this, getAccountId(), name);
task.executeTask();
}
private void setUserListsData(final List<ParcelableUserList> data, final boolean is_my_account) {
mUserListsAdapter.setData(data, true);
mUsersListContainer.setVisibility(View.GONE);
mUserListsContainer.setVisibility(View.VISIBLE);
mCreateUserListContainer.setVisibility(is_my_account ? View.VISIBLE : View.GONE);
}
private void setUserListsData(final List<ParcelableUserList> data, final boolean is_my_account) {
mUserListsAdapter.setData(data, true);
mUsersListContainer.setVisibility(View.GONE);
mUserListsContainer.setVisibility(View.VISIBLE);
mCreateUserListContainer.setVisibility(is_my_account ? View.VISIBLE : View.GONE);
}
private static class GetUserListsTask extends TwidereAsyncTask<Void, Void, SingleResponse<List<ParcelableUserList>>> {
private static class GetUserListsTask extends TwidereAsyncTask<Void, Void, SingleResponse<List<ParcelableUserList>>> {
private static final String FRAGMENT_TAG_GET_USER_LISTS = "get_user_lists";
private final UserListSelectorActivity mActivity;
private final long mAccountId;
private final String mScreenName;
private static final String FRAGMENT_TAG_GET_USER_LISTS = "get_user_lists";
private final UserListSelectorActivity mActivity;
private final long mAccountId;
private final String mScreenName;
GetUserListsTask(final UserListSelectorActivity activity, final long account_id, final String screen_name) {
mActivity = activity;
mAccountId = account_id;
mScreenName = screen_name;
}
GetUserListsTask(final UserListSelectorActivity activity, final long account_id, final String screen_name) {
mActivity = activity;
mAccountId = account_id;
mScreenName = screen_name;
}
@Override
protected SingleResponse<List<ParcelableUserList>> doInBackground(final Void... params) {
final Twitter twitter = getTwitterInstance(mActivity, mAccountId, false);
if (twitter == null) return SingleResponse.getInstance();
try {
final ResponseList<UserList> lists = twitter.getUserLists(mScreenName);
final List<ParcelableUserList> data = new ArrayList<ParcelableUserList>();
boolean is_my_account = mScreenName.equalsIgnoreCase(getAccountScreenName(mActivity, mAccountId));
for (final UserList item : lists) {
final User user = item.getUser();
if (user != null && mScreenName.equalsIgnoreCase(user.getScreenName())) {
if (!is_my_account && user.getId() == mAccountId) {
is_my_account = true;
}
data.add(new ParcelableUserList(item, mAccountId));
}
}
final SingleResponse<List<ParcelableUserList>> result = SingleResponse.getInstance(data);
result.getExtras().putBoolean(EXTRA_IS_MY_ACCOUNT, is_my_account);
return result;
} catch (final TwitterException e) {
e.printStackTrace();
return SingleResponse.getInstance(e);
}
}
@Override
protected SingleResponse<List<ParcelableUserList>> doInBackground(final Void... params) {
final Twitter twitter = getTwitterInstance(mActivity, mAccountId, false);
if (twitter == null) return SingleResponse.getInstance();
try {
final ResponseList<UserList> lists = twitter.getUserLists(mScreenName, true);
final List<ParcelableUserList> data = new ArrayList<ParcelableUserList>();
boolean is_my_account = mScreenName.equalsIgnoreCase(getAccountScreenName(mActivity, mAccountId));
for (final UserList item : lists) {
final User user = item.getUser();
if (user != null && mScreenName.equalsIgnoreCase(user.getScreenName())) {
if (!is_my_account && user.getId() == mAccountId) {
is_my_account = true;
}
data.add(new ParcelableUserList(item, mAccountId));
}
}
final SingleResponse<List<ParcelableUserList>> result = SingleResponse.getInstance(data);
result.getExtras().putBoolean(EXTRA_IS_MY_ACCOUNT, is_my_account);
return result;
} catch (final TwitterException e) {
e.printStackTrace();
return SingleResponse.getInstance(e);
}
}
@Override
protected void onPostExecute(final SingleResponse<List<ParcelableUserList>> result) {
final Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_GET_USER_LISTS);
if (f instanceof DialogFragment) {
((DialogFragment) f).dismiss();
}
if (result.getData() != null) {
mActivity.setUserListsData(result.getData(), result.getExtras().getBoolean(EXTRA_IS_MY_ACCOUNT));
} else if (result.getException() instanceof TwitterException) {
final TwitterException te = (TwitterException) result.getException();
if (te.getStatusCode() == HttpResponseCode.NOT_FOUND) {
mActivity.searchUser(mScreenName);
}
}
}
@Override
protected void onPostExecute(final SingleResponse<List<ParcelableUserList>> result) {
final Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_GET_USER_LISTS);
if (f instanceof DialogFragment) {
((DialogFragment) f).dismiss();
}
if (result.getData() != null) {
mActivity.setUserListsData(result.getData(), result.getExtras().getBoolean(EXTRA_IS_MY_ACCOUNT));
} else if (result.getException() instanceof TwitterException) {
final TwitterException te = (TwitterException) result.getException();
if (te.getStatusCode() == HttpResponseCode.NOT_FOUND) {
mActivity.searchUser(mScreenName);
}
}
}
@Override
protected void onPreExecute() {
SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_GET_USER_LISTS).setCancelable(false);
}
@Override
protected void onPreExecute() {
SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_GET_USER_LISTS).setCancelable(false);
}
}
}
private static class SearchUsersTask extends TwidereAsyncTask<Void, Void, SingleResponse<List<ParcelableUser>>> {
private static class SearchUsersTask extends TwidereAsyncTask<Void, Void, SingleResponse<List<ParcelableUser>>> {
private static final String FRAGMENT_TAG_SEARCH_USERS = "search_users";
private final UserListSelectorActivity mActivity;
private final long mAccountId;
private final String mName;
private static final String FRAGMENT_TAG_SEARCH_USERS = "search_users";
private final UserListSelectorActivity mActivity;
private final long mAccountId;
private final String mName;
SearchUsersTask(final UserListSelectorActivity activity, final long account_id, final String name) {
mActivity = activity;
mAccountId = account_id;
mName = name;
}
SearchUsersTask(final UserListSelectorActivity activity, final long account_id, final String name) {
mActivity = activity;
mAccountId = account_id;
mName = name;
}
@Override
protected SingleResponse<List<ParcelableUser>> doInBackground(final Void... params) {
final Twitter twitter = getTwitterInstance(mActivity, mAccountId, false);
if (twitter == null) return SingleResponse.getInstance();
try {
final ResponseList<User> lists = twitter.searchUsers(mName, 1);
final List<ParcelableUser> data = new ArrayList<ParcelableUser>();
for (final User item : lists) {
data.add(new ParcelableUser(item, mAccountId));
}
return SingleResponse.getInstance(data);
} catch (final TwitterException e) {
e.printStackTrace();
return SingleResponse.getInstance(e);
}
}
@Override
protected SingleResponse<List<ParcelableUser>> doInBackground(final Void... params) {
final Twitter twitter = getTwitterInstance(mActivity, mAccountId, false);
if (twitter == null) return SingleResponse.getInstance();
try {
final ResponseList<User> lists = twitter.searchUsers(mName, 1);
final List<ParcelableUser> data = new ArrayList<>();
for (final User item : lists) {
data.add(new ParcelableUser(item, mAccountId));
}
return SingleResponse.getInstance(data);
} catch (final TwitterException e) {
e.printStackTrace();
return SingleResponse.getInstance(e);
}
}
@Override
protected void onPostExecute(final SingleResponse<List<ParcelableUser>> result) {
final Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_SEARCH_USERS);
if (f instanceof DialogFragment) {
((DialogFragment) f).dismiss();
}
if (result.getData() != null) {
mActivity.setUsersData(result.getData());
}
}
@Override
protected void onPostExecute(final SingleResponse<List<ParcelableUser>> result) {
final Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_SEARCH_USERS);
if (f instanceof DialogFragment) {
((DialogFragment) f).dismiss();
}
if (result.getData() != null) {
mActivity.setUsersData(result.getData());
}
}
@Override
protected void onPreExecute() {
SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_SEARCH_USERS).setCancelable(false);
}
@Override
protected void onPreExecute() {
SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_SEARCH_USERS).setCancelable(false);
}
}
}
}

View File

@ -20,11 +20,14 @@
package org.mariotaku.twidere.adapter;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.util.Pair;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
@ -32,6 +35,7 @@ import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IActivitiesAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.support.UserFragment;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
@ -44,12 +48,13 @@ import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder;
import org.mariotaku.twidere.view.holder.GapViewHolder;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener;
/**
* Created by mariotaku on 15/1/3.
*/
public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> implements Constants,
IActivitiesAdapter<Data>, OnClickListener {
IActivitiesAdapter<Data>, StatusClickListener {
private static final int ITEM_VIEW_TYPE_STUB = 0;
private static final int ITEM_VIEW_TYPE_GAP = 1;
@ -65,9 +70,10 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
private final int mCardBackgroundColor;
private final int mTextSize;
private final int mProfileImageStyle, mMediaPreviewStyle;
private final boolean mCompactCards;
private boolean mLoadMoreIndicatorEnabled;
protected AbsActivitiesAdapter(final Context context) {
protected AbsActivitiesAdapter(final Context context, boolean compact) {
mContext = context;
final TwidereApplication app = TwidereApplication.getInstance(context);
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context);
@ -78,6 +84,7 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mTextSize = preferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
}
@ -86,19 +93,39 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
public abstract int getActivityCount();
@Override
public void onClick(View v) {
}
@Override
public void onStatusClick(StatusViewHolder holder, int position) {
final ParcelableActivity activity = getActivity(position);
final ParcelableStatus status;
if (activity.action == ParcelableActivity.ACTION_MENTION) {
status = activity.target_object_statuses[0];
} else {
status = activity.target_statuses[0];
}
Utils.openStatus(getContext(), status, null);
}
@Override
public void onUserProfileClick(StatusViewHolder holder, int position) {
final Context context = getContext();
final ParcelableActivity activity = getActivity(position);
final ParcelableStatus status;
if (activity.action == ParcelableActivity.ACTION_MENTION) {
status = activity.target_object_statuses[0];
} else {
status = activity.target_statuses[0];
}
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
if (context instanceof FragmentActivity) {
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
} else {
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
}
}
public abstract Data getData();
@ -144,18 +171,42 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
return mLoadMoreIndicatorEnabled;
}
@Override
public void onItemMenuClick(ViewHolder holder, int position) {
}
@Override
public void onItemActionClick(ViewHolder holder, int id, int position) {
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM_VIEW_TYPE_STATUS: {
final View view = mInflater.inflate(R.layout.card_item_status_compat, parent, false);
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_status_compact, parent, false);
} else {
view = mInflater.inflate(R.layout.card_item_status, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor);
}
final StatusViewHolder holder = new StatusViewHolder(view);
holder.setTextSize(getTextSize());
holder.setOnClickListeners(this);
holder.setStatusClickListener(this);
return holder;
}
case ITEM_VIEW_TYPE_TITLE_SUMMARY: {
final View view = mInflater.inflate(R.layout.list_item_activity_title_summary, parent, false);
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_activity_summary_compact, parent, false);
} else {
view = mInflater.inflate(R.layout.card_item_activity_summary, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor);
}
final ActivityTitleSummaryViewHolder holder = new ActivityTitleSummaryViewHolder(this, view);
holder.setTextSize(getTextSize());
return holder;
@ -207,7 +258,7 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
if (position == getActivityCount()) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
} else if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP;

View File

@ -61,7 +61,7 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mTextSize = preferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
if (compact) {
mCardLayoutResource = R.layout.card_item_status_compat;
mCardLayoutResource = R.layout.card_item_status_compact;
} else {
mCardLayoutResource = R.layout.card_item_status;
}
@ -173,7 +173,7 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1) {
if (position == getStatusCount()) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
} else if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP;

View File

@ -34,8 +34,8 @@ public class ParcelableActivitiesAdapter extends AbsActivitiesAdapter<List<Parce
private List<ParcelableActivity> mData;
public ParcelableActivitiesAdapter(Context context) {
super(context);
public ParcelableActivitiesAdapter(Context context, boolean compact) {
super(context,compact);
}
@Override
@ -57,7 +57,7 @@ public class ParcelableActivitiesAdapter extends AbsActivitiesAdapter<List<Parce
@Override
public ParcelableActivity getActivity(int position) {
if (hasLoadMoreIndicator() && position == getItemCount() - 1) return null;
if (position == getActivityCount()) return null;
return mData.get(position);
}

View File

@ -3,7 +3,6 @@ package org.mariotaku.twidere.adapter;
import android.content.Context;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import java.util.List;
@ -21,7 +20,7 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter<List<Parcelabl
@Override
public boolean isGapItem(int position) {
return getStatus(position).is_gap;
return getStatus(position).is_gap && position != getStatusCount() - 1;
}
@Override
@ -31,7 +30,7 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter<List<Parcelabl
@Override
public ParcelableStatus getStatus(int position) {
if (hasLoadMoreIndicator() && position == getStatusCount() - 1) return null;
if (position == getStatusCount()) return null;
return mData.get(position);
}

View File

@ -34,17 +34,16 @@ import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.UserColorNameUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.UserListListViewHolder;
import org.mariotaku.twidere.view.holder.UserListViewListHolder;
import java.util.List;
import java.util.Locale;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.UserColorNameUtils.getDisplayName;
import static org.mariotaku.twidere.util.Utils.getLocalizedNumber;
import static org.mariotaku.twidere.util.Utils.openUserProfile;
public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserList> implements IBaseCardAdapter,
public class ParcelableUserListsListAdapter extends BaseArrayAdapter<ParcelableUserList> implements IBaseCardAdapter,
OnClickListener {
private final Context mContext;
@ -52,11 +51,11 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
private final MultiSelectManager mMultiSelectManager;
private final Locale mLocale;
public ParcelableUserListsAdapter(final Context context) {
public ParcelableUserListsListAdapter(final Context context) {
this(context, Utils.isCompactCards(context));
}
public ParcelableUserListsAdapter(final Context context, final boolean compactCards) {
public ParcelableUserListsListAdapter(final Context context, final boolean compactCards) {
super(context, getItemResource(compactCards));
mContext = context;
mLocale = context.getResources().getConfiguration().locale;
@ -79,11 +78,11 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
final Object tag = view.getTag();
final UserListListViewHolder holder;
if (tag instanceof UserListListViewHolder) {
holder = (UserListListViewHolder) tag;
final UserListViewListHolder holder;
if (tag instanceof UserListViewListHolder) {
holder = (UserListViewListHolder) tag;
} else {
holder = new UserListListViewHolder(view);
holder = new UserListViewListHolder(view);
holder.profile_image.setOnClickListener(this);
// holder.content.setOnOverflowIconClickListener(this);
view.setTag(holder);
@ -97,10 +96,16 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
holder.setTextSize(getTextSize());
holder.name.setText(user_list.name);
holder.created_by.setText(mContext.getString(R.string.created_by, display_name));
holder.description.setVisibility(TextUtils.isEmpty(user_list.description) ? View.GONE : View.VISIBLE);
holder.description.setText(user_list.description);
holder.members_count.setText(getLocalizedNumber(mLocale, user_list.members_count));
holder.subscribers_count.setText(getLocalizedNumber(mLocale, user_list.subscribers_count));
if (holder.description != null) {
holder.description.setVisibility(TextUtils.isEmpty(user_list.description) ? View.GONE : View.VISIBLE);
holder.description.setText(user_list.description);
}
if (holder.members_count != null) {
holder.members_count.setText(getLocalizedNumber(mLocale, user_list.members_count));
}
if (holder.subscribers_count != null) {
holder.subscribers_count.setText(getLocalizedNumber(mLocale, user_list.subscribers_count));
}
holder.profile_image.setVisibility(isDisplayProfileImage() ? View.VISIBLE : View.GONE);
if (isDisplayProfileImage()) {
mImageLoader.displayProfileImage(holder.profile_image, user_list.user_profile_image_url);
@ -143,6 +148,7 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
private static int getItemResource(final boolean compactCards) {
return compactCards ? R.layout.card_item_user_list_compact : R.layout.card_item_user_list;
// return compactCards ? R.layout.card_item_user_list_compact : R.layout.card_item_user_list;
return R.layout.list_item_user_list;
}
}

View File

@ -31,7 +31,7 @@ import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.UserListViewHolder;
import org.mariotaku.twidere.view.holder.UserViewListHolder;
import java.util.List;
import java.util.Locale;
@ -74,11 +74,11 @@ public class ParcelableUsersAdapter extends BaseArrayAdapter<ParcelableUser> imp
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
final Object tag = view.getTag();
final UserListViewHolder holder;
if (tag instanceof UserListViewHolder) {
holder = (UserListViewHolder) tag;
final UserViewListHolder holder;
if (tag instanceof UserViewListHolder) {
holder = (UserViewListHolder) tag;
} else {
holder = new UserListViewHolder(view);
holder = new UserViewListHolder(view);
// holder.content.setOnOverflowIconClickListener(this);
view.setTag(holder);
}

View File

@ -42,6 +42,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private int mOrientation;
private Rect mPadding;
private int mDecorationStart = -1, mDecorationEnd = -1, mDecorationEndOffset;
public DividerItemDecoration(Context context, int orientation) {
mPadding = new Rect();
@ -51,6 +52,21 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
setOrientation(orientation);
}
public void setDecorationStart(int start) {
mDecorationStart = start;
}
public void setDecorationEnd(int end) {
mDecorationEnd = end;
mDecorationEndOffset = -1;
}
public void setDecorationEndOffset(int endOffset) {
mDecorationEndOffset = endOffset;
mDecorationEnd = -1;
}
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
@ -78,6 +94,9 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final int childPos = parent.getChildPosition(child);
final int start = getDecorationStart(), end = getDecorationEnd(parent);
if (start >= 0 && end >= 0 && (childPos < start || childPos > end)) continue;
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin +
@ -96,6 +115,9 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final int childPos = parent.getChildPosition(child);
final int start = getDecorationStart(), end = getDecorationEnd(parent);
if (start >= 0 && end >= 0 && (childPos < start || childPos > end)) continue;
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin +
@ -109,8 +131,9 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
final Adapter adapter = parent.getAdapter();
if (adapter != null && parent.getChildPosition(view) == adapter.getItemCount() - 1) {
final int childPos = parent.getChildPosition(view);
final int start = getDecorationStart(), end = getDecorationEnd(parent);
if (start >= 0 && end >= 0 && childPos < start && childPos > end) {
outRect.setEmpty();
return;
}
@ -120,4 +143,17 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
private int getDecorationEnd(RecyclerView parent) {
if (mDecorationEnd != -1) return mDecorationEnd;
if (mDecorationEndOffset != -1) {
final Adapter adapter = parent.getAdapter();
return adapter.getItemCount() - 1 - mDecorationEndOffset;
}
return -1;
}
private int getDecorationStart() {
return mDecorationStart;
}
}

View File

@ -24,7 +24,7 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
/**
* Created by mariotaku on 14/12/3.
*/
public interface ICardSupportedAdapter {
public interface ContentCardClickListener {
void onItemActionClick(ViewHolder holder, int id, int position);
void onItemMenuClick(ViewHolder holder, int position);

View File

@ -20,22 +20,16 @@
package org.mariotaku.twidere.adapter.iface;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
/**
* Created by mariotaku on 14/11/18.
*/
public interface IActivitiesAdapter<Data> extends IContentCardAdapter {
ParcelableActivity getActivity(int position);
int getActivityCount();
void onStatusClick(StatusViewHolder holder, int position);
void onUserProfileClick(StatusViewHolder holder, int position);
void setData(Data data);
}

View File

@ -20,7 +20,6 @@
package org.mariotaku.twidere.adapter.iface;
import android.content.Context;
import android.support.v7.widget.RecyclerView.ViewHolder;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
@ -29,7 +28,7 @@ import org.mariotaku.twidere.util.ImageLoadingHandler;
/**
* Created by mariotaku on 15/1/3.
*/
public interface IContentCardAdapter extends IGapSupportedAdapter, ICardSupportedAdapter {
public interface IContentCardAdapter extends IGapSupportedAdapter, ContentCardClickListener {
ImageLoaderWrapper getImageLoader();
Context getContext();

View File

@ -2,11 +2,12 @@ package org.mariotaku.twidere.adapter.iface;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener;
/**
* Created by mariotaku on 14/11/18.
*/
public interface IStatusesAdapter<Data> extends IContentCardAdapter {
public interface IStatusesAdapter<Data> extends IContentCardAdapter, StatusClickListener {
ParcelableStatus getStatus(int position);
@ -14,7 +15,4 @@ public interface IStatusesAdapter<Data> extends IContentCardAdapter {
void setData(Data data);
void onUserProfileClick(StatusViewHolder holder, int position);
void onStatusClick(StatusViewHolder holder, int position);
}

View File

@ -23,6 +23,7 @@ import android.annotation.SuppressLint;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebViewFragment;
import org.mariotaku.twidere.Constants;
@ -36,10 +37,15 @@ public class BaseWebViewFragment extends WebViewFragment implements Constants {
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final WebView view = getWebView();
view.setWebViewClient(new DefaultWebViewClient(getActivity()));
view.setWebViewClient(createWebViewClient());
final WebSettings settings = view.getSettings();
settings.setBuiltInZoomControls(true);
settings.setJavaScriptEnabled(true);
WebSettingsAccessor.setAllowUniversalAccessFromFileURLs(settings, true);
}
protected WebViewClient createWebViewClient() {
return new DefaultWebViewClient(getActivity());
}
}

Some files were not shown because too many files have changed in this diff Show More