Add get gallery jpn title

This commit is contained in:
seven332 committed 2016-02-05 23:47:04 +08:00
1 parent a61eb49b27
commit a4568d811e
28 files changed
+1313 -30

No files matched your search

+6
View File
@@ -42,6 +42,12 @@
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name="com.hippo.ehviewer.ui.SettingsActivity"
android:configChanges="screenSize|uiMode"
android:theme="@style/AppTheme"/>
</application>
</manifest>
@@ -0,0 +1,386 @@
/*
* Copyright 2016 Hippo Seven
*
* 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 com.hippo.app;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.CallSuper;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NavUtils;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatCallback;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
public class AppCompatPreferenceActivity extends PreferenceActivity implements AppCompatCallback,
TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
/**
* Support library version of {@link android.app.Activity#getActionBar}.
*
* <p>Retrieve a reference to this activity's ActionBar.
*
* @return The Activity's ActionBar, or null if it does not have one.
*/
@Nullable
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
/**
* Set a {@link android.widget.Toolbar Toolbar} to act as the {@link android.support.v7.app.ActionBar} for this
* Activity window.
*
* <p>When set to a non-null value the {@link #getActionBar()} method will return
* an {@link android.support.v7.app.ActionBar} object that can be used to control the given toolbar as if it were
* a traditional window decor action bar. The toolbar's menu will be populated with the
* Activity's options menu and the navigation button will be wired through the standard
* {@link android.R.id#home home} menu select action.</p>
*
* <p>In order to use a Toolbar within the Activity's window content the application
* must not request the window feature
* {@link android.view.Window#FEATURE_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}.</p>
*
* @param toolbar Toolbar to set as the Activity's action bar
*/
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@NonNull
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) {
if (super.onMenuItemSelected(featureId, item)) {
return true;
}
final ActionBar ab = getSupportActionBar();
if (item.getItemId() == android.R.id.home && ab != null &&
(ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
return onSupportNavigateUp();
}
return false;
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
/**
* Enable extended support library window features.
* <p>
* This is a convenience for calling
* {@link android.view.Window#requestFeature getWindow().requestFeature()}.
* </p>
*
* @param featureId The desired feature as defined in
* {@link android.view.Window} or {@link android.support.v4.view.WindowCompat}.
* @return Returns true if the requested feature is supported and now enabled.
*
* @see android.app.Activity#requestWindowFeature
* @see android.view.Window#requestFeature
*/
public boolean supportRequestWindowFeature(int featureId) {
return getDelegate().requestWindowFeature(featureId);
}
public void supportInvalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
@Override
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
/**
* Notifies the Activity that a support action mode has been started.
* Activity subclasses overriding this method should call the superclass implementation.
*
* @param mode The new action mode.
*/
@Override
@CallSuper
public void onSupportActionModeStarted(ActionMode mode) {
}
/**
* Notifies the activity that a support action mode has finished.
* Activity subclasses overriding this method should call the superclass implementation.
*
* @param mode The action mode that just finished.
*/
@Override
@CallSuper
public void onSupportActionModeFinished(ActionMode mode) {
}
/**
* Called when a support action mode is being started for this window. Gives the
* callback an opportunity to handle the action mode in its own unique and
* beautiful way. If this method returns null the system can choose a way
* to present the mode or choose not to start the mode at all.
*
* @param callback Callback to control the lifecycle of this action mode
* @return The ActionMode that was started, or null if the system should present it
*/
@Nullable
@Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
return null;
}
public ActionMode startSupportActionMode(ActionMode.Callback callback) {
return getDelegate().startSupportActionMode(callback);
}
/**
* Support version of {@link #onCreateNavigateUpTaskStack(android.app.TaskStackBuilder)}.
* This method will be called on all platform versions.
*
* Define the synthetic task stack that will be generated during Up navigation from
* a different task.
*
* <p>The default implementation of this method adds the parent chain of this activity
* as specified in the manifest to the supplied {@link android.support.v4.app.TaskStackBuilder}. Applications
* may choose to override this method to construct the desired task stack in a different
* way.</p>
*
* <p>This method will be invoked by the default implementation of {@link #onNavigateUp()}
* if {@link #shouldUpRecreateTask(android.content.Intent)} returns true when supplied with the intent
* returned by {@link #getParentActivityIntent()}.</p>
*
* <p>Applications that wish to supply extra Intent parameters to the parent stack defined
* by the manifest should override
* {@link #onPrepareSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder)}.</p>
*
* @param builder An empty TaskStackBuilder - the application should add intents representing
* the desired task stack
*/
public void onCreateSupportNavigateUpTaskStack(TaskStackBuilder builder) {
builder.addParentStack(this);
}
/**
* Support version of {@link #onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)}.
* This method will be called on all platform versions.
*
* Prepare the synthetic task stack that will be generated during Up navigation
* from a different task.
*
* <p>This method receives the {@link android.support.v4.app.TaskStackBuilder} with the constructed series of
* Intents as generated by {@link #onCreateSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder)}.
* If any extra data should be added to these intents before launching the new task,
* the application should override this method and add that data here.</p>
*
* @param builder A TaskStackBuilder that has been populated with Intents by
* onCreateNavigateUpTaskStack.
*/
public void onPrepareSupportNavigateUpTaskStack(TaskStackBuilder builder) {
}
/**
* This method is called whenever the user chooses to navigate Up within your application's
* activity hierarchy from the action bar.
*
* <p>If a parent was specified in the manifest for this activity or an activity-alias to it,
* default Up navigation will be handled automatically. See
* {@link #getSupportParentActivityIntent()} for how to specify the parent. If any activity
* along the parent chain requires extra Intent arguments, the Activity subclass
* should override the method {@link #onPrepareSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder)}
* to supply those arguments.</p>
*
* <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and
* Back Stack</a> from the developer guide and
* <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> from the design guide
* for more information about navigating within your app.</p>
*
* <p>See the {@link android.support.v4.app.TaskStackBuilder} class and the Activity methods
* {@link #getSupportParentActivityIntent()}, {@link #supportShouldUpRecreateTask(android.content.Intent)}, and
* {@link #supportNavigateUpTo(android.content.Intent)} for help implementing custom Up navigation.</p>
*
* @return true if Up navigation completed successfully and this Activity was finished,
* false otherwise.
*/
public boolean onSupportNavigateUp() {
Intent upIntent = getSupportParentActivityIntent();
if (upIntent != null) {
if (supportShouldUpRecreateTask(upIntent)) {
TaskStackBuilder b = TaskStackBuilder.create(this);
onCreateSupportNavigateUpTaskStack(b);
onPrepareSupportNavigateUpTaskStack(b);
b.startActivities();
try {
ActivityCompat.finishAffinity(this);
} catch (IllegalStateException e) {
// This can only happen on 4.1+, when we don't have a parent or a result set.
// In that case we should just finish().
finish();
}
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
supportNavigateUpTo(upIntent);
}
return true;
}
return false;
}
/**
* Obtain an {@link android.content.Intent} that will launch an explicit target activity
* specified by sourceActivity's {@link android.support.v4.app.NavUtils#PARENT_ACTIVITY} &lt;meta-data&gt;
* element in the application's manifest. If the device is running
* Jellybean or newer, the android:parentActivityName attribute will be preferred
* if it is present.
*
* @return a new Intent targeting the defined parent activity of sourceActivity
*/
@Override
@Nullable
public Intent getSupportParentActivityIntent() {
return NavUtils.getParentActivityIntent(this);
}
/**
* Returns true if sourceActivity should recreate the task when navigating 'up'
* by using targetIntent.
*
* <p>If this method returns false the app can trivially call
* {@link #supportNavigateUpTo(android.content.Intent)} using the same parameters to correctly perform
* up navigation. If this method returns false, the app should synthesize a new task stack
* by using {@link android.support.v4.app.TaskStackBuilder} or another similar mechanism to perform up navigation.</p>
*
* @param targetIntent An intent representing the target destination for up navigation
* @return true if navigating up should recreate a new task stack, false if the same task
* should be used for the destination
*/
public boolean supportShouldUpRecreateTask(Intent targetIntent) {
return NavUtils.shouldUpRecreateTask(this, targetIntent);
}
/**
* Navigate from sourceActivity to the activity specified by upIntent, finishing sourceActivity
* in the process. upIntent will have the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} set
* by this method, along with any others required for proper up navigation as outlined
* in the Android Design Guide.
*
* <p>This method should be used when performing up navigation from within the same task
* as the destination. If up navigation should cross tasks in some cases, see
* {@link #supportShouldUpRecreateTask(android.content.Intent)}.</p>
*
* @param upIntent An intent representing the target destination for up navigation
*/
public void supportNavigateUpTo(Intent upIntent) {
NavUtils.navigateUpTo(this, upIntent);
}
@Nullable
@Override
public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
return getDelegate().getDrawerToggleDelegate();
}
/**
* @return The {@link AppCompatDelegate} being used by this Activity.
*/
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}
}
@@ -111,13 +111,14 @@ public class Settings {
putBoolean(KEY_SHOW_WARNING, value);
}
public static EhConfig getEhConfig() {
return sEhConfig;
}
private static final String KEY_SHOW_JPN_TITLE = "show_jpn_title";
private static final boolean DEFAULT_SHOW_JPN_TITLE = false;
public static boolean getShowJpnTitle() {
return getBoolean(KEY_SHOW_JPN_TITLE, DEFAULT_SHOW_JPN_TITLE);
}
}
@@ -124,7 +124,7 @@ public class EhClient {
Call call = EhEngine.prepareGetGalleryList(mOkHttpClient, ehConfig, (String) params[0]);
if (!mStop) {
mCall = call;
return EhEngine.doGetGalleryList(call);
return EhEngine.doGetGalleryList(call, (Boolean) params[1], mOkHttpClient);
} else {
throw new CancelledException();
}
@@ -21,18 +21,24 @@ import android.util.Log;
import android.util.Pair;
import com.hippo.ehviewer.client.data.GalleryDetail;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.ehviewer.client.data.LargePreviewSet;
import com.hippo.ehviewer.client.exception.CancelledException;
import com.hippo.ehviewer.client.exception.EhException;
import com.hippo.ehviewer.client.parser.GalleryDetailParser;
import com.hippo.ehviewer.client.parser.GalleryListParser;
import com.hippo.ehviewer.client.parser.ParserUtils;
import com.hippo.ehviewer.client.parser.RateGalleryParser;
import com.hippo.ehviewer.client.parser.SignInParser;
import com.hippo.network.StatusCodeException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Headers;
@@ -117,7 +123,62 @@ public class EhEngine {
return okHttpClient.newCall(request);
}
public static GalleryListParser.Result doGetGalleryList(Call call) throws Exception {
private static GalleryInfo getGalleryInfoByGid(List<GalleryInfo> galleryInfos, int gid) {
for (int i = 0, size = galleryInfos.size(); i < size; i++) {
GalleryInfo gi = galleryInfos.get(i);
if (gi.gid == gid) {
return gi;
}
}
return null;
}
private static void parseGalleryApi(String body, List<GalleryInfo> galleryInfos) throws JSONException {
JSONObject jo = new JSONObject(body);
JSONArray ja = jo.getJSONArray("gmetadata");
for (int i = 0, length = ja.length(); i < length; i++) {
JSONObject g = ja.getJSONObject(i);
int gid = g.getInt("gid");
GalleryInfo gi = getGalleryInfoByGid(galleryInfos, gid);
if (gi == null) {
continue;
}
gi.titleJpn = ParserUtils.trim(g.getString("title_jpn"));
// tags
JSONArray tagJa = g.getJSONArray("tags");
int tagLength = tagJa.length();
String[] tags = new String[tagLength];
for (int j = 0; j < tagLength; j++) {
tags[j] = tagJa.getString(j);
}
gi.simpleTags = tags;
}
}
private static void doRequestGalleryApi(List<GalleryInfo> galleryInfos, OkHttpClient okHttpClient)
throws Exception {
JSONObject json = new JSONObject();
json.put("method", "gdata");
JSONArray ja = new JSONArray();
for (int i = 0, size = galleryInfos.size(); i < size; i++) {
GalleryInfo gi = galleryInfos.get(i);
JSONArray g = new JSONArray();
g.put(gi.gid);
g.put(gi.token);
ja.put(g);
}
json.put("gidlist", ja);
json.put("namespace", 1);
String url = EhUrl.API_EX;
Log.d(TAG, url);
Request request = new EhRequestBuilder(url)
.post(RequestBody.create(JSON, json.toString()))
.build();
Call call = okHttpClient.newCall(request);
String body = null;
Headers headers = null;
int code = -1;
@@ -126,7 +187,41 @@ public class EhEngine {
code = response.code();
headers = response.headers();
body = response.body().string();
return GalleryListParser.parse(body);
parseGalleryApi(body, galleryInfos);
} catch (Exception e) {
throwException(call, code, headers, body, e);
throw e;
}
}
private static void requestGalleryApi(List<GalleryInfo> galleryInfos,
OkHttpClient okHttpClient) throws Exception {
final int MAX_REQUEST_SIZE = 25;
List<GalleryInfo> requestItems = new ArrayList<>(MAX_REQUEST_SIZE);
for (int i = 0, size = galleryInfos.size(); i < size; i++) {
requestItems.add(galleryInfos.get(i));
if (requestItems.size() == MAX_REQUEST_SIZE || i == size - 1) {
doRequestGalleryApi(requestItems, okHttpClient);
requestItems.clear();
}
}
}
public static GalleryListParser.Result doGetGalleryList(Call call, boolean callApi,
OkHttpClient okHttpClient) throws Exception {
String body = null;
Headers headers = null;
int code = -1;
try {
Response response = call.execute();
code = response.code();
headers = response.headers();
body = response.body().string();
GalleryListParser.Result result = GalleryListParser.parse(body);
if (callApi && result.galleryInfos.size() > 0) {
requestGalleryApi(result.galleryInfos, okHttpClient);
}
return result;
} catch (Exception e) {
throwException(call, code, headers, body, e);
throw e;
@@ -216,4 +311,6 @@ public class EhEngine {
throw e;
}
}
// TODO Add get gallery api info
}
@@ -121,10 +121,10 @@ public class EhUtils {
}
public static String getSuitableTitle(GalleryInfo gi) {
if (false) {//;Settings.getJpnTitle()) {
if (Settings.getShowJpnTitle()) {
return TextUtils.isEmpty(gi.titleJpn) ? gi.title : gi.titleJpn;
} else {
return gi.title;
return TextUtils.isEmpty(gi.title) ? gi.titleJpn : gi.title;
}
}
@@ -0,0 +1,98 @@
/*
* Copyright 2016 Hippo Seven
*
* 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 com.hippo.ehviewer.client.data;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
public class GalleryApiInfo implements Parcelable {
public int gid;
public String token;
public String archiverKey;
public String title;
public String titleJpn;
public int category;
public String thumb;
public String uploader;
public long posted;
public int filecount;
public long filesize;
public boolean expunged;
public float rating;
public int torrentcount;
@Nullable
public String[] tags;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.gid);
dest.writeString(this.token);
dest.writeString(this.archiverKey);
dest.writeString(this.title);
dest.writeString(this.titleJpn);
dest.writeInt(this.category);
dest.writeString(this.thumb);
dest.writeString(this.uploader);
dest.writeLong(this.posted);
dest.writeInt(this.filecount);
dest.writeLong(this.filesize);
dest.writeByte(expunged ? (byte) 1 : (byte) 0);
dest.writeFloat(this.rating);
dest.writeInt(this.torrentcount);
dest.writeStringArray(this.tags);
}
public GalleryApiInfo() {
}
protected GalleryApiInfo(Parcel in) {
this.gid = in.readInt();
this.token = in.readString();
this.archiverKey = in.readString();
this.title = in.readString();
this.titleJpn = in.readString();
this.category = in.readInt();
this.thumb = in.readString();
this.uploader = in.readString();
this.posted = in.readLong();
this.filecount = in.readInt();
this.filesize = in.readLong();
this.expunged = in.readByte() != 0;
this.rating = in.readFloat();
this.torrentcount = in.readInt();
this.tags = in.createStringArray();
}
public static final Parcelable.Creator<GalleryApiInfo> CREATOR = new Parcelable.Creator<GalleryApiInfo>() {
@Override
public GalleryApiInfo createFromParcel(Parcel source) {
return new GalleryApiInfo(source);
}
@Override
public GalleryApiInfo[] newArray(int size) {
return new GalleryApiInfo[size];
}
};
}
@@ -86,6 +86,7 @@ public class GalleryInfo implements Parcelable {
public String posted;
public String uploader;
public float rating;
public String[] simpleTags;
/**
* language from title
@@ -16,7 +16,9 @@
package com.hippo.ehviewer.ui;
import android.content.Intent;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.IdRes;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
@@ -36,8 +38,11 @@ import com.hippo.scene.StageActivity;
public final class MainActivity extends StageActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static final String KEY_NAV_CHECKED_ITEM = "nav_checked_item";
private DrawerLayout mDrawerLayout;
private NavigationView mNavView;
private int mNavCheckedItem = 0;
@Override
public int getContainerViewId() {
@@ -56,9 +61,43 @@ public final class MainActivity extends StageActivity
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void onInit() {
if (Settings.getShowWarning()) {
setDrawerLayoutEnable(false);
startScene(WarningScene.class);
} else if (!EhUtils.hasSignedIn(this)) {
setDrawerLayoutEnable(false);
startScene(LoginScene.class);
} else {
setDrawerLayoutEnable(true);
Bundle args = new Bundle();
args.putString(GalleryListScene.KEY_ACTION, GalleryListScene.ACTION_HOMEPAGE);
startScene(GalleryListScene.class, args);
}
}
private void onRestore(Bundle savedInstanceState) {
mNavCheckedItem = savedInstanceState.getInt(KEY_NAV_CHECKED_ITEM);
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putInt(KEY_NAV_CHECKED_ITEM, mNavCheckedItem);
}
@Override
protected void onResume() {
super.onResume();
setNavCheckedItem(mNavCheckedItem);
}
public void setDrawerLayoutEnable(boolean enable) {
if (enable) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
@@ -76,6 +115,7 @@ public final class MainActivity extends StageActivity
}
public void setNavCheckedItem(@IdRes int resId) {
mNavCheckedItem = resId;
if (resId == 0) {
mNavView.setCheckedItem(R.id.nav_stub);
} else {
@@ -83,21 +123,6 @@ public final class MainActivity extends StageActivity
}
}
private void onInit() {
if (Settings.getShowWarning()) {
setDrawerLayoutEnable(false);
startScene(WarningScene.class);
} else if (!EhUtils.hasSignedIn(this)) {
setDrawerLayoutEnable(false);
startScene(LoginScene.class);
} else {
setDrawerLayoutEnable(true);
Bundle args = new Bundle();
args.putString(GalleryListScene.KEY_ACTION, GalleryListScene.ACTION_HOMEPAGE);
startScene(GalleryListScene.class, args);
}
}
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(Gravity.LEFT) || mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
@@ -109,7 +134,11 @@ public final class MainActivity extends StageActivity
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
// Don't select twice
if (item.isChecked()) {
return false;
}
int id = item.getItemId();
if (id == R.id.nav_homepage) {
@@ -125,7 +154,8 @@ public final class MainActivity extends StageActivity
} else if (id == R.id.nav_download) {
} else if (id == R.id.nav_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
if (id != R.id.nav_stub) {
@@ -0,0 +1,191 @@
/*
* Copyright 2016 Hippo Seven
*
* 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 com.hippo.ehviewer.ui;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import com.hippo.app.AppCompatPreferenceActivity;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.fragment.EhFragment;
import com.hippo.vector.VectorDrawable;
import java.lang.reflect.Field;
import java.util.List;
public final class SettingsActivity extends AppCompatPreferenceActivity {
private static final int REQUEST_CODE_FRAGMENT = 0;
private static final String[] ENTRY_FRAGMENTS = {
EhFragment.class.getName(),
};
private class FakeLayoutInflater extends LayoutInflater {
private LayoutInflater mInflater;
protected FakeLayoutInflater(LayoutInflater inflater) {
super(null);
mInflater = inflater;
}
@Override
public LayoutInflater cloneInContext(Context newContext) {
return null;
}
@Override
public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
return mInflater.inflate(R.layout.item_preference_header, root, attachToRoot);
}
}
@SuppressWarnings("TryWithIdenticalCatches")
private void replaceHeaderLayoutResId() {
try {
ListAdapter adapter = getListAdapter();
Class headerAdapterClazz = Class.forName("android.preference.PreferenceActivity$HeaderAdapter");
if (!headerAdapterClazz.isInstance(adapter)) {
return;
}
boolean ok = false;
// For lollipop and above this work
try {
Field field = headerAdapterClazz.getDeclaredField("mLayoutResId");
field.setAccessible(true);
field.setInt(adapter, R.layout.item_preference_header);
ok = true;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// For pre-lollipop this work
if (!ok) {
try {
Field field = headerAdapterClazz.getDeclaredField("mInflater");
field.setAccessible(true);
field.set(adapter, new FakeLayoutInflater((LayoutInflater) field.get(adapter)));
ok = true;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
}
}
if (ok) {
getListView().setDivider(new ColorDrawable(Color.TRANSPARENT));
getListView().setDividerHeight(0);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void setActionBarUpIndicator(Drawable drawable) {
ActionBarDrawerToggle.Delegate delegate = getDrawerToggleDelegate();
if (delegate != null) {
delegate.setActionBarUpIndicator(drawable, 0);
}
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setActionBarUpIndicator(VectorDrawable.create(this, R.drawable.ic_arrow_left));
replaceHeaderLayoutResId();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.settings_headers, target);
}
@Override
public void startWithFragment(String fragmentName, Bundle args,
Fragment resultTo, int resultRequestCode, @StringRes int titleRes,
@StringRes int shortTitleRes) {
Intent intent = onBuildStartFragmentIntent(fragmentName, args, titleRes, shortTitleRes);
if (resultTo == null) {
startActivityForResult(intent, REQUEST_CODE_FRAGMENT);
} else {
resultTo.startActivityForResult(intent, resultRequestCode);
}
}
@Override
protected boolean isValidFragment(String fragmentName) {
for (String fragment : ENTRY_FRAGMENTS) {
if (fragment.equals(fragmentName)) {
return true;
}
}
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_FRAGMENT) {
if (resultCode == RESULT_OK) {
setResult(RESULT_OK, data);
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2016 Hippo Seven
*
* 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 com.hippo.ehviewer.ui.fragment;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import com.hippo.ehviewer.R;
public class EhFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.eh_settings);
}
}
@@ -578,7 +578,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
if (ACTION_GALLERY_INFO.equals(mAction) && mGalleryInfo != null) {
GalleryInfo gi = mGalleryInfo;
mThumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb, true);
mTitle.setText(gi.title);
mTitle.setText(EhUtils.getSuitableTitle(gi));
mUploader.setText(gi.uploader);
mCategory.setText(EhUtils.getCategory(gi.category));
mCategory.setTextColor(EhUtils.getCategoryColor(gi.category));
@@ -618,7 +618,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
if (TextUtils.isEmpty(mCategory.getText())) {
mThumb.load(EhCacheKeyFactory.getThumbKey(gd.gid), gd.thumb, true);
mTitle.setText(gd.title);
mTitle.setText(EhUtils.getSuitableTitle(gd));
mUploader.setText(gd.uploader);
mCategory.setText(EhUtils.getCategory(gd.category));
mCategory.setTextColor(EhUtils.getCategoryColor(gd.category));
@@ -53,6 +53,7 @@ import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.FastScroller;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.client.EhCacheKeyFactory;
import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.client.EhRequest;
@@ -926,7 +927,7 @@ public final class GalleryListScene extends BaseScene
public void onBindViewHolder(GalleryListHolder holder, int position) {
GalleryInfo gi = mHelper.getDataAt(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb, true);
holder.title.setText(gi.title);
holder.title.setText(EhUtils.getSuitableTitle(gi));
holder.uploader.setText(gi.uploader);
holder.rating.setRating(gi.rating);
TextView category = holder.category;
@@ -965,7 +966,7 @@ public final class GalleryListScene extends BaseScene
request.setMethod(EhClient.METHOD_GET_GALLERY_LIST);
request.setCallback(new GetGalleryListListener(getContext(),
((StageActivity) getActivity()).getStageId(), getTag(), taskId));
request.setArgs(url);
request.setArgs(url, Settings.getShowJpnTitle()); // TODO check tag filter
mClient.execute(request);
}
@@ -0,0 +1,190 @@
/*
* Copyright 2015 Hippo Seven
*
* 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 com.hippo.preference;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.preference.TwoStatePreference;
import android.support.annotation.StringRes;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Checkable;
import android.widget.CompoundButton;
import com.hippo.ehviewer.R;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class FixedSwitchPreference extends TwoStatePreference {
private static Method sSyncSummaryViewMethod;
static {
try {
sSyncSummaryViewMethod = TwoStatePreference.class.getDeclaredMethod("syncSummaryView", View.class);
sSyncSummaryViewMethod.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
sSyncSummaryViewMethod = null;
}
}
// Switch text for on and off states
private CharSequence mSwitchOn;
private CharSequence mSwitchOff;
private final Listener mListener = new Listener();
private class Listener implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!callChangeListener(isChecked)) {
// Listener didn't like it, change it back.
// CompoundButton will make sure we don't recurse.
buttonView.setChecked(!isChecked);
return;
}
FixedSwitchPreference.this.setChecked(isChecked);
}
}
public FixedSwitchPreference(Context context) {
super(context);
init(context, null, 0, 0);
}
public FixedSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0, 0);
}
public FixedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr, 0);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public FixedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs, defStyleAttr, defStyleRes);
}
public void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FixedSwitchPreference, defStyleAttr, defStyleRes);
setSummaryOn(a.getString(R.styleable.FixedSwitchPreference_summaryOn));
setSummaryOff(a.getString(R.styleable.FixedSwitchPreference_summaryOff));
setSwitchTextOn(a.getString(R.styleable.FixedSwitchPreference_switchTextOn));
setSwitchTextOff(a.getString(R.styleable.FixedSwitchPreference_switchTextOff));
setDisableDependentsState(a.getBoolean(R.styleable.FixedSwitchPreference_disableDependentsState, false));
a.recycle();
}
@SuppressWarnings("TryWithIdenticalCatches")
@Override
protected void onBindView(View view) {
super.onBindView(view);
View checkableView = view.findViewById(R.id.switchWidget);
if (checkableView != null && checkableView instanceof Checkable) {
if (checkableView instanceof SwitchCompat) {
final SwitchCompat switchView = (SwitchCompat) checkableView;
switchView.setOnCheckedChangeListener(null);
}
((Checkable) checkableView).setChecked(isChecked());
if (checkableView instanceof SwitchCompat) {
final SwitchCompat switchView = (SwitchCompat) checkableView;
switchView.setTextOn(mSwitchOn);
switchView.setTextOff(mSwitchOff);
switchView.setOnCheckedChangeListener(mListener);
}
}
if (sSyncSummaryViewMethod != null) {
try {
sSyncSummaryViewMethod.invoke(this, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* Set the text displayed on the switch widget in the on state.
* This should be a very short string; one word if possible.
*
* @param onText Text to display in the on state
*/
public void setSwitchTextOn(CharSequence onText) {
mSwitchOn = onText;
notifyChanged();
}
/**
* Set the text displayed on the switch widget in the off state.
* This should be a very short string; one word if possible.
*
* @param offText Text to display in the off state
*/
public void setSwitchTextOff(CharSequence offText) {
mSwitchOff = offText;
notifyChanged();
}
/**
* Set the text displayed on the switch widget in the on state.
* This should be a very short string; one word if possible.
*
* @param resId The text as a string resource ID
*/
public void setSwitchTextOn(@StringRes int resId) {
setSwitchTextOn(getContext().getString(resId));
}
/**
* Set the text displayed on the switch widget in the off state.
* This should be a very short string; one word if possible.
*
* @param resId The text as a string resource ID
*/
public void setSwitchTextOff(@StringRes int resId) {
setSwitchTextOff(getContext().getString(resId));
}
/**
* @return The text that will be displayed on the switch widget in the on state
*/
public CharSequence getSwitchTextOn() {
return mSwitchOn;
}
/**
* @return The text that will be displayed on the switch widget in the off state
*/
public CharSequence getSwitchTextOff() {
return mSwitchOff;
}
}
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2015 Hippo Seven
~
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:color="@color/colorPrimary"/>
<item android:state_enabled="false" android:color="@color/primary_text_disabled_light"/>
<item android:color="@color/primary_text_default_light"/>
</selector>
Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2015 Hippo Seven
~
~ 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="@drawable/grey_500"/>
<item android:drawable="@drawable/transparent"/>
</selector>
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2015 Hippo Seven
~
~ 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="72dp"
android:orientation="horizontal"
android:background="@drawable/preference_header_background">
<ImageView
android:id="@android:id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:scaleType="centerInside"
android:layout_marginLeft="16dp"
android:layout_marginRight="32dp"
android:contentDescription="@null"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="@color/preference_header_title_light"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
<View
android:id="@+id/tile_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/dividerVertical" />
</LinearLayout>
</LinearLayout>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2015 Hippo Seven
~
~ 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.
-->
<!-- Layout used by SwitchPreference for the switch widget style. This is inflated
inside android.R.layout.preference. -->
<android.support.v7.widget.SwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/switchWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="16dp"
android:focusable="false"/>
+20
View File
@@ -88,4 +88,24 @@
<attr name="dark" format="boolean"/>
</declare-styleable>
<declare-styleable name="FixedSwitchPreference">
<!-- The summary for the Preference in a PreferenceActivity screen when the
SwitchPreference is checked. If separate on/off summaries are not
needed, the summary attribute can be used instead. -->
<attr name="summaryOn" format="string"/>
<!-- The summary for the Preference in a PreferenceActivity screen when the
SwitchPreference is unchecked. If separate on/off summaries are not
needed, the summary attribute can be used instead. -->
<attr name="summaryOff" format="string"/>
<!-- The text used on the switch itself when in the "on" state.
This should be a very SHORT string, as it appears in a small space. -->
<attr name="switchTextOn" format="string"/>
<!-- The text used on the switch itself when in the "off" state.
This should be a very SHORT string, as it appears in a small space. -->
<attr name="switchTextOff" format="string"/>
<!-- The state (true for on, or false for off) that causes dependents to be disabled. By default,
dependents will be disabled when this is unchecked, so the value of this preference is false. -->
<attr name="disableDependentsState" format="boolean"/>
</declare-styleable>
</resources>
+2
View File
@@ -28,6 +28,7 @@
<!-- Text -->
<color name="primary_text_default_light">#de000000</color>
<color name="primary_text_default_light_inverse">#ffffffff</color>
<color name="primary_text_disabled_dark">#4dffffff</color>
<color name="secondary_text_default_light">#8a000000</color>
<color name="secondary_text_disabled_dark">#36ffffff</color>
@@ -50,6 +51,7 @@
<color name="light_green_600">#ff7cb342</color>
<color name="yellow_800">#fff9a825</color>
<color name="deep_orange_400">#ffff7043</color>
<color name="grey_500">#ff9e9e9e</color>
<color name="colorPrimary">@color/teal_500</color>
<color name="colorPrimaryDark">@color/teal_700</color>
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2015 Hippo Seven
~
~ 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.
-->
<resources>
<drawable name="grey_500">@color/grey_500</drawable>
<drawable name="transparent">@android:color/transparent</drawable>
</resources>
+5
View File
@@ -201,6 +201,11 @@
<string name="go_to">Go to</string>
<string name="error_out_of_range">Out of range</string>
<string name="settings_eh_title">EH</string>
<string name="settings_eh_show_jpn_title_title">Show Japanese title</string>
<string name="settings_eh_show_jpn_title_summary_on">Try to show Japanese title. It takes more time to get gallery list</string>
<string name="settings_eh_show_jpn_title_summary_off">Show default title. It is usually English title</string>
<!-- Readable Time -->
<string name="from_the_future">From the future</string>
<string name="just_now">Just now</string>
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2016 Hippo Seven
~
~ 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.hippo.preference.FixedSwitchPreference
style="?android:attr/preferenceStyle"
android:widgetLayout="@layout/preference_widget_fixed_switch"
android:key="show_jpn_title"
android:title="@string/settings_eh_show_jpn_title_title"
app:summaryOn="@string/settings_eh_show_jpn_title_summary_on"
app:summaryOff="@string/settings_eh_show_jpn_title_summary_off"
android:defaultValue="false"/>
</PreferenceScreen>
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2016 Hippo Seven
~
~ 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.
-->
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.hippo.ehviewer.ui.fragment.EhFragment"
android:title="@string/settings_eh_title"
android:icon="@drawable/ic_settings_eh"/>
</preference-headers>