自定义textView无法按预期工作

时间:2017-12-25 02:32:14

标签: java android

我有一个自定义textview如下

public class TaskTitleView extends TextView {
    public static final int NORMAL = 0;
    public static final int DONE = 1;
    public static final int OVERDUE = 2;
    private int mState;

    public TaskTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public TaskTitleView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TaskTitleView(Context context) {
        super(context);
    }

    /**
     * Return the current display state of this view.
     *
     * @return One of {@link #NORMAL}, {@link #DONE}, or {@link #OVERDUE}.
     */
    public int getState() {
        return mState;
    }

    /**
     * Update the text display state of this view.
     * Normal status shows black text. Overdue displays in red.
     * Completed draws a strikethrough line on the text.
     *
     * @param state New state. One of {@link #NORMAL}, {@link #DONE}, or {@link #OVERDUE}.
     */
    public void setState(int state) {
        switch (state) {
            case DONE:
                setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG);
                Log.i("vvv","vvvv");
                setTextColor(ContextCompat.getColor(getContext(), R.color.black));
            case NORMAL:
                setPaintFlags(0);
                setTextColor(ContextCompat.getColor(getContext(), R.color.black));
                break;
            case OVERDUE:
                setPaintFlags(0);
                setTextColor(ContextCompat.getColor(getContext(), R.color.red));
                break;
            default:
                return;
        }

        mState = state;
    }
}

在recyclerView适配器上,我做了类似这样的事情

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskHolder> {

    /* Callback for list item click events */
    public interface OnItemClickListener {
        void onItemClick(View v, int position);

        void onItemToggled(boolean active, int position);
    }

    /* ViewHolder for each task item */
    public class TaskHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TaskTitleView nameView;
        public TextView dateView;
        public ImageView priorityView;
        public CheckBox checkBox;

        public TaskHolder(View itemView) {
            super(itemView);

            nameView = (TaskTitleView) itemView.findViewById(R.id.text_description);
            //nameView= new TaskTitleView(mContext);
            dateView = (TextView) itemView.findViewById(R.id.text_date);
            priorityView = (ImageView) itemView.findViewById(R.id.priority);
            checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);

            itemView.setOnClickListener(this);
            checkBox.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (v == checkBox) {
                completionToggled(this);
            } else {

                postItemClick(this);
            }
        }
    }

    private Cursor mCursor;
    private OnItemClickListener mOnItemClickListener;
    private Context mContext;

    public TaskAdapter(Cursor cursor, Context context) {
        mCursor = cursor;
        mContext = context;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
    }

    private void completionToggled(TaskHolder holder) {
        if (mOnItemClickListener != null) {
            mOnItemClickListener.onItemToggled(holder.checkBox.isChecked(),holder.getAdapterPosition());
        }
    }

    private void postItemClick(TaskHolder holder) {
        if (mOnItemClickListener != null) {
            int adapterPosition = holder.getAdapterPosition();
            mCursor.moveToPosition(adapterPosition);
            mOnItemClickListener.onItemClick(holder.itemView, Integer.parseInt(mCursor.getString(mCursor.getColumnIndex(DatabaseContract.TaskColumns._ID))));
            Log.i("rrr",mCursor.getString(mCursor.getColumnIndex(DatabaseContract.TaskColumns._ID)));

        }
    }

    @Override
    public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        mContext = parent.getContext();
        View itemView = LayoutInflater.from(mContext)
                .inflate(R.layout.list_item_task, parent, false);

        return new TaskHolder(itemView);
    }

    @Override
    public void onBindViewHolder(TaskHolder holder, int position) {

        Log.i("test", String.valueOf(position));
        mCursor.moveToPosition(position);
        holder.nameView.setText(mCursor.getString(mCursor.getColumnIndex(DatabaseContract.TaskColumns.DESCRIPTION)));
        holder.nameView.setState(0);
        if(mCursor.getLong(mCursor.getColumnIndex(DatabaseContract.TaskColumns.DUE_DATE))==Long.MAX_VALUE)
        {

        }
        else {
            CharSequence formatted = DateUtils.getRelativeTimeSpanString(mCursor.getLong(mCursor.getColumnIndex(DatabaseContract.TaskColumns.DUE_DATE)));
            holder.dateView.setText(formatted);
        }

        if(mCursor.getString(mCursor.getColumnIndex(DatabaseContract.TaskColumns.IS_PRIORITY)).equals("0"))
        {

            holder.priorityView.setImageDrawable(mContext.getDrawable(R.drawable.ic_not_priority));
        }
        else
        {
            holder.priorityView.setImageDrawable(mContext.getDrawable(R.drawable.ic_priority));
        }

        if(mCursor.getString(mCursor.getColumnIndex(DatabaseContract.TaskColumns.IS_COMPLETE)).equals("1"))
        {
            holder.nameView.setState(1);
            holder.checkBox.setChecked(true);
        }
        else
        {
            holder.nameView.setState(0);
            holder.checkBox.setChecked(false);
        }
    }

    @Override
    public int getItemCount() {
        return (mCursor != null) ? mCursor.getCount() : 0;
    }

    /**
     * Retrieve a {@link Task} for the data at the given position.
     *
     * @param position Adapter item position.
     *
     * @return A new {@link Task} filled with the position's attributes.
     */
    public Task getItem(int position) {
        if (!mCursor.moveToPosition(position)) {
            throw new IllegalStateException("Invalid item position requested");
        }

        return new Task(mCursor);
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).id;
    }

    public void swapCursor(Cursor cursor) {
        if (mCursor != null) {
            mCursor.close();
        }
        mCursor = cursor;
        notifyDataSetChanged();
    }
}

什么是错的,当我改变状态时,它应该改变。但我什么也没看到。甚至不是文字。 请帮忙。 谢谢 .................................................. ......................... .........................................

3 个答案:

答案 0 :(得分:0)

在自定义invalidate();上设置状态时,您可以添加TextView

public void setState(int state) {
    switch (state) {
        case DONE:
            setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG);
            Log.i("vvv","vvvv");
            setTextColor(ContextCompat.getColor(getContext(), R.color.color_black));
        case NORMAL:
            setPaintFlags(0);
            setTextColor(ContextCompat.getColor(getContext(), R.color.color_blue));
            break;
        case OVERDUE:
            setPaintFlags(0);
            setTextColor(ContextCompat.getColor(getContext(), R.color.color_red));
            break;
        default:
            return;
    }

    mState = state;
    // add here , to update 
    invalidate();
}

更改

@Override
public void onClick(View v) {
    if (v == checkBox) {
        completionToggled(this);
    } else {

        postItemClick(this);
    }
}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.checkbox:
            completionToggled(this);
            break;
        default:
            postItemClick(this);
            break;
    }
}

答案 1 :(得分:0)

试试这个

 public class Textview_Bold extends TextView {


    public Textview_Bold(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public Textview_Bold(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public Textview_Bold(Context context) {
        super(context);
        init();
    }

    private void init() {
        if (!isInEditMode()) {
            Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Lato-Bold.ttf");
            setTypeface(tf);
        }
    }   
}

<强> XML

<yourpackage name.FontText.Textview_Bold
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#000"
                    android:text="Create Account"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:padding="5dp"
                    android:id="@+id/createaccount"
                    android:background="@drawable/buttonselector"
                    android:layout_alignParentTop="true"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentEnd="true" />

答案 2 :(得分:0)

您需要更改customView生命周期中的属性,或者在覆盖的事件中使用func。

在您的情况下,请尝试按照下一步更新您的观点:

查看更新

  

从视图生命周期图中,您可能会注意到有两种方法可以引导视图重绘自身。 invalidate()和requestLayout()方法将帮助您创建交互式自定义视图,这可能会在运行时更改其外观。但为什么有两个?   invalidate()方法用于简单重绘视图。例如,您的视图会更新其文本,颜色或触摸交互性。这意味着视图将再次调用onDraw()方法来更新其状态。   requestLayout()方法,正如您所看到的那样,只需从onMeasure()方法生成视图更新。这意味着你需要它在你的视图更新后,它改变了它的大小,你需要再次测量它,以根据新的大小绘制它。

从这里开始:https://medium.com/@romandanylyk96/android-draw-a-custom-view-ef79fe2ff54b