Added floating labels to replyfragment.

captchafix
Florens Douwes 12 years ago
parent 53175d2143
commit bd43fc5947
  1. 21
      Chan/assets/html/licences.html
  2. 12
      Chan/res/anim/slide_from_bottom.xml
  3. 12
      Chan/res/anim/slide_to_bottom.xml
  4. 20
      Chan/res/layout/floatlabel_edittext.xml
  5. 300
      Chan/res/layout/reply_view.xml
  6. 12
      Chan/res/values/attrs.xml
  7. 4
      Chan/res/values/colors.xml
  8. 233
      Chan/src/com/micromobs/android/floatlabel/FloatLabelEditText.java
  9. 2
      Chan/src/org/floens/chan/adapter/PostAdapter.java
  10. 25
      Chan/src/org/floens/chan/fragment/ReplyFragment.java
  11. 5
      Chan/src/org/floens/chan/loader/Loader.java
  12. 2
      Chan/src/org/floens/chan/manager/ThreadManager.java

@ -74,6 +74,27 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
</code>
</pre>
<br>
<h3>AndroidFloatLabel from Weddingparty</h3>
<a href="https://github.com/weddingparty/AndroidFloatLabel">https://github.com/weddingparty/AndroidFloatLabel</a>
<pre>
<code>
Copyright (C) 2014 AndroidFloatLabel team
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.
</code>
</pre>
<br>
</body>
</html>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="5%p"
android:toYDelta="0"
android:duration="350" />
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="350" />
</set>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="5%p"
android:duration="350" />
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="350" />
</set>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_marginTop="5dp"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/floating_label_hint"
android:layout_width="wrap_content"
android:visibility="invisible"
android:layout_height="wrap_content"
android:layout_marginBottom="-8dp"/>
<EditText
android:id="@+id/floating_label_edit_text"
android:layout_width="wrap_content"
android:hint="tmp"
android:layout_height="wrap_content"/>
</LinearLayout>

@ -1,149 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:floatlabel="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="600dp"
android:minHeight="500dp"
android:orientation="vertical"
android:divider="?android:attr/dividerHorizontal"
android:showDividers="middle" >
android:showDividers="middle" >
<ViewFlipper
android:id="@+id/reply_flipper"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/reply_data"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="@+id/reply_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_name" />
<EditText
android:id="@+id/reply_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_email"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/reply_subject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_subject" />
<EditText
android:id="@+id/reply_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_comment"
android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
android:imeActionLabel="@string/reply_submit"
android:minLines="2" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/reply_file"
android:text="@string/reply_file" />
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/reply_file_delete"
android:text="@string/reply_file_delete" />
</LinearLayout>
<org.floens.chan.utils.LoadView
android:id="@+id/reply_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<ScrollView
<ViewFlipper
android:id="@+id/reply_flipper"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="vertical" >
<org.floens.chan.utils.LoadView
android:id="@+id/reply_captcha_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/reply_captcha_tap_to_reload" />
<EditText
android:id="@+id/reply_captcha"
android:hint="@string/reply_captcha"
android:inputType="textNoSuggestions"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
<org.floens.chan.utils.LoadView
android:id="@+id/reply_response"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</org.floens.chan.utils.LoadView>
</ViewFlipper>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/buttonBarStyle" >
<Button
android:id="@+id/reply_cancel"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
android:id="@+id/reply_submit"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/reply_submit" />
</LinearLayout>
<LinearLayout
android:id="@+id/reply_data"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!--<EditText
android:id="@+id/reply_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_name" />-->
<com.micromobs.android.floatlabel.FloatLabelEditText
android:id="@+id/reply_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
floatlabel:fitScreenWidth="full"
floatlabel:textSize="20sp"
floatlabel:hint="@string/reply_name"
floatlabel:textColorHintFocused="@color/holo_blue_dark"
floatlabel:textColorHintUnFocused="@android:color/darker_gray" />
<com.micromobs.android.floatlabel.FloatLabelEditText
android:id="@+id/reply_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
floatlabel:fitScreenWidth="full"
floatlabel:textSize="20sp"
floatlabel:hint="@string/reply_email"
floatlabel:textColorHintFocused="@color/holo_blue_dark"
floatlabel:textColorHintUnFocused="@android:color/darker_gray" />
<com.micromobs.android.floatlabel.FloatLabelEditText
android:id="@+id/reply_subject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
floatlabel:fitScreenWidth="full"
floatlabel:textSize="20sp"
floatlabel:hint="@string/reply_subject"
floatlabel:textColorHintFocused="@color/holo_blue_dark"
floatlabel:textColorHintUnFocused="@android:color/darker_gray" />
<com.micromobs.android.floatlabel.FloatLabelEditText
android:id="@+id/reply_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
android:minLines="5"
android:imeActionLabel="@string/reply_submit"
floatlabel:fitScreenWidth="full"
floatlabel:textSize="20sp"
floatlabel:hint="@string/reply_comment"
floatlabel:textColorHintFocused="@color/holo_blue_dark"
floatlabel:textColorHintUnFocused="@android:color/darker_gray" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/reply_file"
android:text="@string/reply_file" />
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/reply_file_delete"
android:text="@string/reply_file_delete" />
</LinearLayout>
<org.floens.chan.utils.LoadView
android:id="@+id/reply_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="200dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="vertical" >
<org.floens.chan.utils.LoadView
android:id="@+id/reply_captcha_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/reply_captcha_tap_to_reload" />
<EditText
android:id="@+id/reply_captcha"
android:hint="@string/reply_captcha"
android:inputType="textNoSuggestions"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
<org.floens.chan.utils.LoadView
android:id="@+id/reply_response"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</org.floens.chan.utils.LoadView>
</ViewFlipper>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/buttonBarStyle" >
<Button
android:id="@+id/reply_cancel"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
android:id="@+id/reply_submit"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/reply_submit" />
</LinearLayout>
</LinearLayout>

@ -1,4 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="image_list_background">#88000000</color>
<declare-styleable name="FloatLabelEditText">
<attr name="hint" format="string"/>
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColorHintFocused" format="color"/>
<attr name="textColorHintUnFocused" format="color"/>
<attr name="fitScreenWidth" format="enum">
<enum name="full" value="1"/>
<enum name="half" value="2"/>
</attr>
</declare-styleable>
</resources>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="holo_blue_dark">#ff0099cc</color>
</resources>

@ -0,0 +1,233 @@
package com.micromobs.android.floatlabel;
import org.floens.chan.R;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
@TargetApi(11)
public class FloatLabelEditText extends LinearLayout {
private int mFocusedColor, mUnFocusedColor, mFitScreenWidth;
private final int mCurrentApiVersion = android.os.Build.VERSION.SDK_INT;
private float mTextSizeInSp;
private String mHintText, mEditText;
private AttributeSet mAttrs;
private final Context mContext;
private EditText mEditTextView;
private TextView mFloatingLabel;
// -----------------------------------------------------------------------
// default constructors
public FloatLabelEditText(Context context) {
super(context);
mContext = context;
initializeView();
}
public FloatLabelEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mAttrs = attrs;
initializeView();
}
public FloatLabelEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
mAttrs = attrs;
initializeView();
}
// -----------------------------------------------------------------------
// public interface
public EditText getEditText() {
return mEditTextView;
}
public String getText() {
if (getEditTextString() != null &&
getEditTextString().toString() != null &&
getEditTextString().toString().length() > 0) {
return getEditTextString().toString();
}
return "";
}
// -----------------------------------------------------------------------
// private helpers
private void initializeView() {
if (mContext == null) return;
LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mInflater.inflate(R.layout.floatlabel_edittext, this, true);
mFloatingLabel = (TextView) findViewById(R.id.floating_label_hint);
mEditTextView = (EditText) findViewById(R.id.floating_label_edit_text);
getAttributesFromXmlAndStoreLocally();
setupEditTextView();
setupFloatingLabel();
}
private void getAttributesFromXmlAndStoreLocally() {
TypedArray attributesFromXmlLayout = mContext.obtainStyledAttributes(mAttrs, R.styleable.FloatLabelEditText );
if (attributesFromXmlLayout == null) return;
mHintText = attributesFromXmlLayout.getString(R.styleable.FloatLabelEditText_hint);
mEditText = attributesFromXmlLayout.getString(R.styleable.FloatLabelEditText_text);
mTextSizeInSp = getScaledFontSize(attributesFromXmlLayout.getDimensionPixelSize(R.styleable.FloatLabelEditText_textSize, (int) mEditTextView.getTextSize()));
mFocusedColor = attributesFromXmlLayout.getColor(R.styleable.FloatLabelEditText_textColorHintFocused, android.R.color.black);
mUnFocusedColor = attributesFromXmlLayout.getColor(R.styleable.FloatLabelEditText_textColorHintUnFocused, android.R.color.darker_gray);
mFitScreenWidth = attributesFromXmlLayout.getInt(R.styleable.FloatLabelEditText_fitScreenWidth, 0);
attributesFromXmlLayout.recycle();
}
private void setupEditTextView() {
mEditTextView.setHint(mHintText);
mEditTextView.setHintTextColor(mUnFocusedColor);
mEditTextView.setText(mEditText);
mEditTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeInSp);
mEditTextView.addTextChangedListener(getTextWatcher());
if (mFitScreenWidth > 0) {
mEditTextView.setWidth(getSpecialWidth());
}
if (mCurrentApiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
mEditTextView.setOnFocusChangeListener(getFocusChangeListener());
}
}
private void setupFloatingLabel() {
mFloatingLabel.setText(mHintText);
mFloatingLabel.setTextColor(mUnFocusedColor);
mFloatingLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, (float) (mTextSizeInSp / 1.3));
mFloatingLabel.setPadding(mEditTextView.getPaddingLeft(), 0, 0, 0);
if (getText().length() > 0) {
showFloatingLabel();
}
}
private TextWatcher getTextWatcher() {
return new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > 0 && mFloatingLabel.getVisibility() == INVISIBLE) {
showFloatingLabel();
} else if (s.length() == 0 && mFloatingLabel.getVisibility() == VISIBLE) {
hideFloatingLabel();
}
}
};
}
private void showFloatingLabel() {
mFloatingLabel.setVisibility(VISIBLE);
mFloatingLabel.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.slide_from_bottom));
}
private void hideFloatingLabel() {
mFloatingLabel.setVisibility(INVISIBLE);
mFloatingLabel.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.slide_to_bottom));
}
private OnFocusChangeListener getFocusChangeListener() {
return new OnFocusChangeListener() {
ValueAnimator mFocusToUnfocusAnimation, mUnfocusToFocusAnimation;
@Override
public void onFocusChange(View v, boolean hasFocus) {
ValueAnimator lColorAnimation;
if (hasFocus) {
lColorAnimation = getFocusToUnfocusAnimation();
} else {
lColorAnimation = getUnfocusToFocusAnimation();
}
lColorAnimation.setDuration(700);
lColorAnimation.start();
}
private ValueAnimator getFocusToUnfocusAnimation() {
if (mFocusToUnfocusAnimation == null) {
mFocusToUnfocusAnimation = getFocusAnimation(mUnFocusedColor, mFocusedColor);
}
return mFocusToUnfocusAnimation;
}
private ValueAnimator getUnfocusToFocusAnimation() {
if (mUnfocusToFocusAnimation == null) {
mUnfocusToFocusAnimation = getFocusAnimation(mFocusedColor, mUnFocusedColor);
}
return mUnfocusToFocusAnimation;
}
};
}
private ValueAnimator getFocusAnimation(int fromColor, int toColor) {
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), fromColor, toColor);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
mFloatingLabel.setTextColor((Integer) animator.getAnimatedValue());
}
});
return colorAnimation;
}
private Editable getEditTextString() {
return mEditTextView.getText();
}
private float getScaledFontSize(float fontSizeFromAttributes) {
float scaledDensity = getContext().getResources().getDisplayMetrics().scaledDensity;
return fontSizeFromAttributes/scaledDensity;
}
@SuppressWarnings({ "deprecation", "unused" })
private int getSpecialWidth() {
float screenWidth = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
int prevWidth = mEditTextView.getWidth();
switch (mFitScreenWidth) {
case 2:
return (int) Math.round(screenWidth * 0.5);
default:
return Math.round(screenWidth);
}
}
}

@ -130,7 +130,7 @@ public class PostAdapter extends BaseAdapter {
public void scrollToPost(Post post) {
for (int i = 0; i < postList.size(); i++) {
if (postList.get(i) == post) {
if (postList.get(i).no == post.no) {
listView.smoothScrollToPosition(i);
break;

@ -42,6 +42,7 @@ import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.StringRequest;
import com.micromobs.android.floatlabel.FloatLabelEditText;
public class ReplyFragment extends DialogFragment {
private static final String TAG = "ReplyFragment";
@ -63,10 +64,10 @@ public class ReplyFragment extends DialogFragment {
private Button fileButton;
private Button fileDeleteButton;
private Button submitButton;
private TextView nameView;
private TextView emailView;
private TextView subjectView;
private TextView commentView;
private FloatLabelEditText nameView;
private FloatLabelEditText emailView;
private FloatLabelEditText subjectView;
private FloatLabelEditText commentView;
private LoadView imageViewContainer;
private LoadView captchaContainer;
private TextView captchaText;
@ -132,10 +133,10 @@ public class ReplyFragment extends DialogFragment {
draft.email = ChanPreferences.getDefaultEmail();
}
nameView.setText(draft.name);
emailView.setText(draft.email);
subjectView.setText(draft.subject);
commentView.setText(draft.comment);
nameView.getEditText().setText(draft.name);
emailView.getEditText().setText(draft.email);
subjectView.getEditText().setText(draft.subject);
commentView.getEditText().setText(draft.comment);
setFile(draft.file);
getCaptcha();
@ -178,10 +179,10 @@ public class ReplyFragment extends DialogFragment {
container = inflater.inflate(R.layout.reply_view, null);
flipper = (ViewFlipper)container.findViewById(R.id.reply_flipper);
nameView = (TextView)container.findViewById(R.id.reply_name);
emailView = (TextView)container.findViewById(R.id.reply_email);
subjectView = (TextView)container.findViewById(R.id.reply_subject);
commentView = (TextView)container.findViewById(R.id.reply_comment);
nameView = (FloatLabelEditText)container.findViewById(R.id.reply_name);
emailView = (FloatLabelEditText)container.findViewById(R.id.reply_email);
subjectView = (FloatLabelEditText)container.findViewById(R.id.reply_subject);
commentView = (FloatLabelEditText)container.findViewById(R.id.reply_comment);
imageViewContainer = (LoadView)container.findViewById(R.id.reply_image);
responseContainer = (LoadView)container.findViewById(R.id.reply_response);
captchaContainer = (LoadView)container.findViewById(R.id.reply_captcha_container);

@ -66,8 +66,6 @@ public class Loader {
request.cancel();
}
postsById.clear();
if (loadable.isBoardMode()) {
loadable.no = 0;
loadable.listViewIndex = 0;
@ -109,7 +107,7 @@ public class Loader {
return request != null;
}
public Post getPostById(int id) {
public Post findPostById(int id) {
return postsById.get(id);
}
@ -196,6 +194,7 @@ public class Loader {
private void onData(List<Post> result) {
if (destroyed) return;
postsById.clear();
for (Post post : result) {
postsById.append(post.no, post);
}

@ -131,7 +131,7 @@ public class ThreadManager implements Loader.LoaderListener {
public Post findPostById(int id) {
if (loader == null) return null;
return loader.getPostById(id);
return loader.findPostById(id);
}
public Loadable getLoadable() {

Loading…
Cancel
Save