类android.text.SpannableStringBuilder源码实例Demo

下面列出了怎么用android.text.SpannableStringBuilder的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: android-chromium   文件: ConfirmInfoBar.java
@Override
public CharSequence getMessageText(Context context) {
    // Construct text to be displayed on the infobar.
    SpannableStringBuilder infobarMessage = new SpannableStringBuilder(mMessage);

    // If we have a link text to display, append it.
    if (!TextUtils.isEmpty(mLinkText)) {
        SpannableStringBuilder spannableLinkText = new SpannableStringBuilder(mLinkText);
        ClickableSpan onLinkClicked = new ClickableSpan() {
            @Override
            public void onClick(View view) {
                onLinkClicked();
            }
        };
        spannableLinkText.setSpan(onLinkClicked, 0, spannableLinkText.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        infobarMessage.append(" ");
        infobarMessage.append(spannableLinkText);
    }
    return infobarMessage;
}
 
源代码2 项目: Markwon   文件: SpannableBuilderTest.java
@Test
public void spans_reversed() {
    // resulting SpannableStringBuilder should have spans reversed

    final Object[] spans = {
            0,
            1,
            2
    };

    for (Object span : spans) {
        builder.append(span.toString(), span);
    }

    final SpannableStringBuilder spannableStringBuilder = builder.spannableStringBuilder();
    final Object[] actual = spannableStringBuilder.getSpans(0, builder.length(), Object.class);

    for (int start = 0, length = spans.length, end = length - 1; start < length; start++, end--) {
        assertEquals(spans[start], actual[end]);
    }
}
 
源代码3 项目: 365browser   文件: PermissionDialogController.java
private CharSequence prepareMainMessageString(final PermissionDialogDelegate delegate) {
    SpannableStringBuilder fullString = new SpannableStringBuilder();

    String messageText = delegate.getMessageText();
    String linkText = delegate.getLinkText();
    if (!TextUtils.isEmpty(messageText)) fullString.append(messageText);

    // If the linkText exists, then wrap it in a clickable span and concatenate it with the main
    // dialog message.
    if (!TextUtils.isEmpty(linkText)) {
        if (fullString.length() > 0) fullString.append(" ");
        int spanStart = fullString.length();

        fullString.append(linkText);
        fullString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View view) {
                mDecision = NOT_DECIDED;
                delegate.onLinkClicked();
                if (mDialog != null) mDialog.dismiss();
            }
        }, spanStart, fullString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return fullString;
}
 
源代码4 项目: Markwon   文件: MarkwonEditorImplTest.java
@Test
public void process() {
    // create markwon
    final Markwon markwon = Markwon.create(RuntimeEnvironment.application);

    // default punctuation
    final MarkwonEditor editor = MarkwonEditor.create(markwon);

    final SpannableStringBuilder builder = new SpannableStringBuilder("**bold**");

    editor.process(builder);

    final PunctuationSpan[] spans = builder.getSpans(0, builder.length(), PunctuationSpan.class);
    assertEquals(2, spans.length);

    final PunctuationSpan first = spans[0];
    assertEquals(0, builder.getSpanStart(first));
    assertEquals(2, builder.getSpanEnd(first));

    final PunctuationSpan second = spans[1];
    assertEquals(6, builder.getSpanStart(second));
    assertEquals(8, builder.getSpanEnd(second));
}
 
源代码5 项目: TelePlus-Android   文件: EmojiView.java
private void sendEmoji(String override) {
    String code = override != null ? override : (String) getTag();
    SpannableStringBuilder builder = new SpannableStringBuilder();
    builder.append(code);
    if (override == null) {
        if (pager.getCurrentItem() != 0) {
            String color = Emoji.emojiColor.get(code);
            if (color != null) {
                code = addColorToCode(code, color);
            }
        }
        addEmojiToRecent(code);
        if (listener != null) {
            listener.onEmojiSelected(Emoji.fixEmoji(code));
        }
    } else {
        if (listener != null) {
            listener.onEmojiSelected(Emoji.fixEmoji(override));
        }
    }
}
 
源代码6 项目: GSYRickText   文件: RichEditText.java
/**
 * 添加了@的加入
 *
 * @param userModel 用户实体
 */
public void resolveText(UserModel userModel) {
    String userName = userModel.getUser_name();
    userModel.setUser_name(userName + "\b");
    nameList.add(userModel);

    int index = getSelectionStart();
    SpannableStringBuilder spannableStringBuilder =
            new SpannableStringBuilder(getText());
    //直接用span会导致后面没文字的时候新输入的一起变色
    Spanned htmlText = Html.fromHtml(String.format("<font color='%s'>" + userName + "</font>", colorAtUser));
    spannableStringBuilder.insert(index, htmlText);
    spannableStringBuilder.insert(index + htmlText.length(), "\b");
    setText(spannableStringBuilder);
    setSelection(index + htmlText.length() + 1);
}
 
源代码7 项目: Overchan-Android   文件: HtmlParser.java
public HtmlToSpannedConverter(String subject, String source, ThemeColors colors, HtmlParser.ImageGetter imageGetter, boolean openSpoilers,
        Parser parser) {
    mSource = source;
    mSpannableStringBuilder = new SpannableStringBuilder();
    if (!TextUtils.isEmpty(subject)) {
        mSpannableStringBuilder.append(subject);
        int len = mSpannableStringBuilder.length();
        mSpannableStringBuilder.setSpan(new RelativeSizeSpan(1.25f), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        mSpannableStringBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        if (colors != null) {
            mSpannableStringBuilder.setSpan(new ForegroundColorSpan(colors.subjectForeground), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        mSpannableStringBuilder.append('\n');
        mStartLength = mSpannableStringBuilder.length();
    }
    mColors = colors;
    mOpenSpoilers = openSpoilers;
    mImageGetter = imageGetter;
    mReader = parser;
}
 
源代码8 项目: Overchan-Android   文件: HtmlParser.java
private static void endBlockquote(SpannableStringBuilder text, ThemeColors colors) {
    int len = text.length();
    Object obj = getLast(text, Blockquote.class);
    int where = text.getSpanStart(obj);
    text.removeSpan(obj);
    
    if (where != len) {
        Blockquote b = (Blockquote) obj;
        if (b.mIsUnkfunc) {
            if (colors != null) {
                text.setSpan(new ForegroundColorSpan(colors.quoteForeground), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        } else {
            text.setSpan(new QuoteSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
}
 
源代码9 项目: talk-android   文件: MessageFormatter.java
public static Spannable formatHighlightSpan(String html, Resources res) {
    HighlightSpan highlightSpan;
    if (Html.fromHtml(html) instanceof SpannableStringBuilder) {
        SpannableStringBuilder value = (SpannableStringBuilder) Html.fromHtml(html);
        StyleSpan[] spans = value.getSpans(0, html.length(), StyleSpan.class);
        for (StyleSpan span : spans) {
            int start = value.getSpanStart(span);
            int end = value.getSpanEnd(span);
            value.removeSpan(span);
            highlightSpan = new HighlightSpan(res);
            value.setSpan(highlightSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return value;
    } else {
        return new SpannableStringBuilder(html);
    }
}
 
源代码10 项目: android-proguards   文件: ImageSpanTarget.java
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
    TextView tv = textView.get();
    if (tv != null) {
        BitmapDrawable bitmapDrawable = new BitmapDrawable(tv.getResources(), bitmap);
        // image span doesn't handle scaling so we manually set bounds
        if (bitmap.getWidth() > tv.getWidth()) {
            float aspectRatio = (float) bitmap.getHeight() / (float) bitmap.getWidth();
            bitmapDrawable.setBounds(0, 0, tv.getWidth(), (int) (aspectRatio * tv.getWidth()));
        } else {
            bitmapDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
        }
        ImageSpan span = new ImageSpan(bitmapDrawable);
        // add the image span and remove our marker
        SpannableStringBuilder ssb = new SpannableStringBuilder(tv.getText());
        int start = ssb.getSpanStart(loadingSpan);
        int end = ssb.getSpanEnd(loadingSpan);
        if (start >= 0 && end >= 0) {
            ssb.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        ssb.removeSpan(loadingSpan);
        // animate the change
        TransitionManager.beginDelayedTransition((ViewGroup) tv.getParent());
        tv.setText(ssb);
    }
}
 
源代码11 项目: Overchan-Android   文件: HtmlParser.java
private static void handleP(SpannableStringBuilder text, int startLength, int[] lastPTagLengthRefs) {
    lastPTagLengthRefs[0] = text.length();
    int len = text.length() - startLength;

    if (len >= 1 && text.charAt(text.length() - 1) == '\n') {
        if (len >= 2 && text.charAt(text.length() - 2) == '\n') {
            lastPTagLengthRefs[1] = text.length();
            return;
        }

        text.append("\n");
        lastPTagLengthRefs[1] = text.length();
        return;
    }

    if (len != 0) {
        text.append("\n\n");
    }
    lastPTagLengthRefs[1] = text.length();
}
 
源代码12 项目: px-android   文件: CreditCardDescriptorModel.java
@Override
protected String getAccessibilityContentDescription(@NonNull final Context context) {
    final SpannableStringBuilder builder = new SpannableStringBuilder();
    final PayerCost currentInstallment = getCurrent();
    final String money = context.getResources().getString(R.string.px_money);
    builder
        .append(currentInstallment.getInstallments().toString())
        .append(TextUtil.SPACE)
        .append(context.getResources().getString(R.string.px_date_divider))
        .append(TextUtil.SPACE)
        .append(currentInstallment.getInstallmentAmount().toString())
        .append(TextUtil.SPACE)
        .append(money)
        .append(TextUtil.SPACE)
        .append(hasAmountDescriptor() ? currentInstallment.getTotalAmount().floatValue() + money : TextUtil.EMPTY)
        .append(hasInterestFree() ? interestFree.getInstallmentRow().getMessage() : TextUtil.EMPTY);

    updateCFTSpannable(builder, context);
    updateInstallmentsInfo(builder, context);

    return builder.toString();
}
 
源代码13 项目: 365browser   文件: AnswerTextBuilder.java
/**
 * Builds a Spannable containing all of the styled text in the supplied ImageLine.
 *
 * @param line All text fields within this line will be added to the returned Spannable.
 *             types.
 * @param metrics Font metrics which will be used to properly size and layout images and top-
 *                aligned text.
 * @param density Screen density which will be used to properly size and layout images and top-
 *                aligned text.
 */
static Spannable buildSpannable(
        SuggestionAnswer.ImageLine line, Paint.FontMetrics metrics, float density) {
    SpannableStringBuilder builder = new SpannableStringBuilder();

    // Determine the height of the largest text element in the line.  This
    // will be used to top-align text and scale images.
    int maxTextHeightSp = getMaxTextHeightSp(line);

    List<SuggestionAnswer.TextField> textFields = line.getTextFields();
    for (int i = 0; i < textFields.size(); i++) {
        appendAndStyleText(builder, textFields.get(i), maxTextHeightSp, metrics, density);
    }
    if (line.hasAdditionalText()) {
        builder.append("  ");
        SuggestionAnswer.TextField additionalText = line.getAdditionalText();
        appendAndStyleText(builder, additionalText, maxTextHeightSp, metrics, density);
    }
    if (line.hasStatusText()) {
        builder.append("  ");
        SuggestionAnswer.TextField statusText = line.getStatusText();
        appendAndStyleText(builder, statusText, maxTextHeightSp, metrics, density);
    }

    return builder;
}
 
源代码14 项目: AIIA-DNN-benchmark   文件: ImageClassifierTF.java
/** Classifies a frame from the preview stream. */
void classifyFrame(Bitmap bitmap, SpannableStringBuilder builder) {
  if (tflite == null) {
    Log.e(TAG, "Image classifier has not been initialized; Skipped.");
    builder.append(new SpannableString("Uninitialized Classifier."));
  }
  convertBitmapToByteBuffer(bitmap);
  // Here's where the magic happens!!!
  long startTime = SystemClock.uptimeMillis();
  runInference();
  long endTime = SystemClock.uptimeMillis();
  Log.d(TAG, "Timecost to run model inference: " + Long.toString(endTime - startTime));

  // Smooth the results across frames.
  applyFilter();

  // Print the results.
  printTopKLabels(builder);
  long duration = endTime - startTime;
  SpannableString span = new SpannableString(duration + " ms");
  span.setSpan(new ForegroundColorSpan(android.graphics.Color.LTGRAY), 0, span.length(), 0);
  builder.append(span);
}
 
源代码15 项目: GSYRickText   文件: SmileUtils.java
public static SpannableStringBuilder highlight(String text) {
    SpannableStringBuilder spannable = new SpannableStringBuilder(text);
    CharacterStyle span = null;
    span = new ForegroundColorSpan(Color.rgb(253, 113, 34));// 需要重复!
    spannable.setSpan(span, 0, text.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spannable;
}
 
protected CharSequence getStyledMessage(@NonNull Recipient recipient, @Nullable CharSequence message) {
  SpannableStringBuilder builder = new SpannableStringBuilder();
  builder.append(Util.getBoldedString(recipient.toShortString(context)));
  builder.append(": ");
  builder.append(message == null ? "" : message);

  return builder;
}
 
源代码17 项目: mvvm-template   文件: DrawableHandler.java
@Override public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
    String src = node.getAttributeByName("src");
    if (!InputHelper.isEmpty(src)) {
        builder.append("");
        if (isNull()) return;
        DrawableGetter imageGetter = new DrawableGetter(textView, width);
        builder.setSpan(new ImageSpan(imageGetter.getDrawable(src)), start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
        builder.setSpan(new CenterSpan(), start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
        appendNewLine(builder);
    }
}
 
源代码18 项目: delion   文件: NotificationPlatformBridge.java
/**
 * Creates the ticker text for a notification having |title| and |body|. The notification's
 * title will be printed in bold, followed by the text of the body.
 *
 * @param title Title of the notification.
 * @param body Textual contents of the notification.
 * @return A character sequence containing the ticker's text.
 */
private CharSequence createTickerText(String title, String body) {
    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();

    spannableStringBuilder.append(title);
    spannableStringBuilder.append("\n");
    spannableStringBuilder.append(body);

    // Mark the title of the notification as being bold.
    spannableStringBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
            0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);

    return spannableStringBuilder;
}
 
源代码19 项目: Telegram-FOSS   文件: TermsOfServiceView.java
public void show(int account, TLRPC.TL_help_termsOfService tos) {
    if (getVisibility() != VISIBLE) {
        setVisibility(VISIBLE);
    }
    SpannableStringBuilder builder = new SpannableStringBuilder(tos.text);
    MessageObject.addEntitiesToText(builder, tos.entities, false, false, false, false);
    addBulletsToText(builder, '-', AndroidUtilities.dp(10f), 0xff50a8eb, AndroidUtilities.dp(4f));
    textView.setText(builder);
    currentTos = tos;
    currentAccount = account;
}
 
源代码20 项目: mollyim-android   文件: EmojiTextView.java
private void ellipsizeAnyTextForMaxLength() {
  if (maxLength > 0 && getText().length() > maxLength + 1) {
    SpannableStringBuilder newContent = new SpannableStringBuilder();
    newContent.append(getText().subSequence(0, maxLength)).append(ELLIPSIS).append(Optional.fromNullable(overflowText).or(""));

    EmojiParser.CandidateList newCandidates = EmojiProvider.getInstance(getContext()).getCandidates(newContent);

    if (useSystemEmoji || newCandidates == null || newCandidates.size() == 0) {
      super.setText(newContent, BufferType.NORMAL);
    } else {
      CharSequence emojified = EmojiProvider.getInstance(getContext()).emojify(newCandidates, newContent, this);
      super.setText(emojified, BufferType.SPANNABLE);
    }
  }
}
 
源代码21 项目: actionbarextras   文件: ActionbarextrasModule.java
/**
 * Helper function to process font objects used for title and subtitle
 * 
 * @param Context - TiApplication context
 * @param Object - the properties as hashmap
 * @param Text - SpannableStringBuilder that should get the properties applied
 * @param TypefaceSpan - font reference (for title or subtitle)
 */
private SpannableStringBuilder applyFontProperties(TiApplication appContext, HashMap<String, String> d, SpannableStringBuilder ssb, TypefaceSpan font){
	
	if (d.containsKey(TiC.PROPERTY_FONTFAMILY)){
		String fontFamily = d.get(TiC.PROPERTY_FONTFAMILY).replaceAll("\\.(ttf|otf|fnt)$", "");
		font = new TypefaceSpan(appContext, fontFamily);
		ssb.setSpan(font, 0, ssb.length(),
				Spannable.SPAN_INCLUSIVE_INCLUSIVE);
	}
	
	if (d.containsKey(TiC.PROPERTY_FONTSIZE)){
		Object value = d.get(TiC.PROPERTY_FONTSIZE);
		boolean dip = false;
		int fontSize;
		
		if (value instanceof String){
			// is there a better way to convert Strings ("16px", "22sp" etc.) to dip?
			fontSize = (int) TiUIHelper.getRawSize(
					TiUIHelper.getSizeUnits((String) value), 
					TiUIHelper.getSize((String) value), 
					appContext
			);
		}else {
			fontSize = (Integer) value;
			dip = true;
		}
		
		ssb.setSpan(new AbsoluteSizeSpan(fontSize, dip), 0, ssb.length(),
				Spannable.SPAN_INCLUSIVE_INCLUSIVE);
	}
	
	if (d.containsKey(TiC.PROPERTY_FONTWEIGHT)){
		String fontWeight = d.get(TiC.PROPERTY_FONTWEIGHT);
		ssb.setSpan(new StyleSpan(TiUIHelper.toTypefaceStyle(fontWeight, null)), 0, ssb.length(),
				Spannable.SPAN_INCLUSIVE_INCLUSIVE);
	}
	
	return ssb;
}
 
源代码22 项目: LaunchEnr   文件: AllAppsContainerView.java
public AllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    mLauncher = Launcher.getLauncher(context);
    mApps = new AlphabeticalAppsList(context);
    mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this);
    mApps.setAdapter(mAdapter);
    mLayoutManager = mAdapter.getLayoutManager();
    mSearchQueryBuilder = new SpannableStringBuilder();
    mSearchContainerMinHeight
            = getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);

    Selection.setSelection(mSearchQueryBuilder, 0);
}
 
源代码23 项目: EmoticonGIFKeyboard   文件: EmoticonEditText.java
@Override
@CallSuper
public void setText(CharSequence rawText, BufferType type) {
    final CharSequence text = rawText == null ? "" : rawText;
    final SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
    if (mEmoticonProvider != null)
        EmoticonUtils.replaceWithImages(getContext(), spannableStringBuilder, mEmoticonProvider, mEmoticonSize);
    super.setText(text, type);
}
 
源代码24 项目: MediaSDK   文件: Tx3gDecoder.java
@SuppressWarnings("ReferenceEquality")
private static void attachFontFamily(SpannableStringBuilder cueText, String fontFamily,
    String defaultFontFamily, int start, int end, int spanPriority) {
  if (fontFamily != defaultFontFamily) {
    cueText.setSpan(new TypefaceSpan(fontFamily), start, end,
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | spanPriority);
  }
}
 
源代码25 项目: TelePlus-Android   文件: TtmlNode.java
private static SpannableStringBuilder getRegionOutput(
    String resolvedRegionId, Map<String, SpannableStringBuilder> regionOutputs) {
  if (!regionOutputs.containsKey(resolvedRegionId)) {
    regionOutputs.put(resolvedRegionId, new SpannableStringBuilder());
  }
  return regionOutputs.get(resolvedRegionId);
}
 
源代码26 项目: Slide   文件: SubmissionCache.java
public static SpannableStringBuilder getCrosspostLine(Submission s, Context mContext) {
    if (crosspost == null) crosspost = new WeakHashMap<>();
    if (crosspost.containsKey(s.getFullName())) {
        return crosspost.get(s.getFullName());
    } else {
        return getCrosspostSpannable(s, mContext);
    }
}
 
源代码27 项目: talk-android   文件: EmojiconTextView.java
@Override
public void setText(CharSequence text, BufferType type) {
    if (!TextUtils.isEmpty(text)) {
        SpannableStringBuilder builder = new SpannableStringBuilder(text);
        EmojiconHandler.addEmojis(getContext(), builder, mEmojiconSize, mTextStart, mTextLength, mUseSystemDefault);
        text = builder;
    }
    super.setText(text, type);
}
 
源代码28 项目: Markdown   文件: StyleBuilderImpl.java
@Override
public SpannableStringBuilder ol(CharSequence charSequence, int level, int index) {
    SpannableStringBuilder spannableStringBuilder = SpannableStringBuilder.valueOf(charSequence);
    BulletSpan bulletSpan = new MarkDownBulletSpan(level, h1_text_color, index);
    spannableStringBuilder.setSpan(bulletSpan, 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spannableStringBuilder;
}
 
源代码29 项目: imsdk-android   文件: MedalRemindProcessor.java
@Override
    public void processChatView(ViewGroup parent, final IMessageItem item) {
        IMMessage message = item.getMessage();
        final Context context = item.getContext();
        try {
            MedalRemindDataBean meetingDataBean = JsonUtils.getGson().fromJson(message.getExt()
                    , MedalRemindDataBean.class);
            MedalClickRemindView meetingRemindView = ViewPool.getView(MedalClickRemindView.class, context);
            SpannableStringBuilder sb = new SpannableStringBuilder();
            String[] strs = meetingDataBean.getStrMap().getAllStr().split(meetingDataBean.getStrMap().getHighlightStr());
            Spanned color = Html.fromHtml("<font color='#00cabe'>" + meetingDataBean.getStrMap().getHighlightStr() + "</font>");

            if (strs.length > 1) {
                sb.append(strs[0]);
                sb.append(color);
                sb.append(strs[1]);
            }
            meetingRemindView.setSB(sb);


            meetingRemindView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

//                    context.startActivity(  FlutterMedalActivity.makeIntent(context,CurrentPreference.getInstance().getPreferenceUserId()));
                }
            });
            parent.setVisibility(View.VISIBLE);
            parent.addView(meetingRemindView);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
 
源代码30 项目: kaif-android   文件: DefaultDecorator.java
private void appendParagraphNewLines(SpannableStringBuilder out) {
  int len = out.length();
  if (len >= 1 && out.charAt(len - 1) == '\n') {
    if (len >= 2 && out.charAt(len - 2) == '\n') {
      return;
    }

    out.append("\n");
    return;
  }

  if (out.length() != 0) {
    out.append("\n\n");
  }
}
 
 类所在包
 同包方法