首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自定义textView未按预期工作

自定义textView未按预期工作
EN

Stack Overflow用户
提问于 2017-12-25 10:32:14
回答 3查看 404关注 0票数 0

我有一个自定义的文本视图,如下所示

代码语言:javascript
运行
复制
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适配器上,我执行了如下操作

代码语言:javascript
运行
复制
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();
    }
}

怎么了,当我改变状态时,它应该改变。但我什么也没看到。连一条短信都没有。请帮帮忙。谢谢............................................................................

EN

回答 3

Stack Overflow用户

发布于 2017-12-25 10:46:20

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

代码语言:javascript
运行
复制
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();
}

变化

代码语言:javascript
运行
复制
@Override
public void onClick(View v) {
    if (v == checkBox) {
        completionToggled(this);
    } else {

        postItemClick(this);
    }
}

代码语言:javascript
运行
复制
@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.checkbox:
            completionToggled(this);
            break;
        default:
            postItemClick(this);
            break;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2017-12-25 14:54:54

尝试此

代码语言:javascript
运行
复制
 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

代码语言:javascript
运行
复制
<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" />
票数 0
EN

Stack Overflow用户

发布于 2017-12-25 15:41:34

你需要在你的customView的生命周期中改变属性,或者让你的函数在被重写的事件中。

在你的例子中,试着更新你的视图,遵循下一步:

视图更新

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47965291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档